Làm thế nào để tự động đẩy sau khi cam kết trong git?


84

Làm cách nào để đặt git tự động đẩy đến một đại diện từ xa (bao gồm cả tự động cung cấp cụm mật khẩu của tôi) sau mỗi lần cam kết với đại diện cục bộ?


1
Bạn đang đẩy qua giao thức nào? Nếu nó nhắc nhập mật khẩu, tôi cho rằng đây là SSH hoặc HTTP.
Mark Longair

1
Ngoài ra, sẽ luôn hữu ích với các câu hỏi git để ít nhất đề cập đến hệ điều hành bạn đang sử dụng.
Mark Longair

1
Tôi đặt câu hỏi về sự khôn ngoan của một thiết lập như vậy. Điều này loại bỏ mọi khả năng sắp xếp lại các thay đổi của bạn thành một nhóm cam kết khác (đặc biệt là giảm giá). Tôi mắc quá nhiều lỗi để một thiết lập như thế này cuối cùng lại có ích cho tôi.
jpmc26

Câu trả lời:


139

Trước tiên, hãy đảm bảo rằng bạn có thể đẩy theo cách thủ công mà không cần cung cấp mật khẩu. Nếu bạn đang đẩy qua HTTP hoặc HTTPS, đó sẽ là trường hợp tạo .netrctệp với chi tiết đăng nhập hoặc thêm tên người dùng và mật khẩu của bạn vào URL cho điều khiển từ xa . Nếu đang sử dụng SSH, bạn có thể tạo một cặp khóa trong đó khóa riêng tư không có mật khẩu hoặc sử dụng ssh-agentđể lưu khóa cá nhân vào bộ nhớ cache .

Sau đó, bạn nên tạo một tệp thực thi ( chmod +x) trong .git/hooks/post-commitđó có chứa những thứ sau:

#!/bin/sh
git push origin master

... tùy chỉnh dòng đó nếu bạn muốn đẩy đến một điều khiển từ xa khác originhoặc đẩy một chi nhánh khác với master. Đảm bảo rằng bạn làm cho tệp đó có thể thực thi được.


3
Không thể làm cho ssh-agent nhớ cụm mật khẩu của tôi, vì vậy phải làm cho nó trống. Hy vọng vợ tôi sẽ không hack tài khoản của tôi :)
ulu

Nói về tùy chỉnh, điều gì sẽ xảy ra nếu tôi muốn đẩy một số nhưng không phải tất cả các nhánh theo cách này? Ví dụ: tôi muốn chỉ tự động đẩy các nhánh có nhánh từ xa tương ứng được ghi chú .git/configbằng tiền tố feature/xy/.
Acumenus

5
git push - all origin
Yada

4
chmod + x .git / móc / post-cam
UnchartedWorks

33

Nếu bạn bắt đầu sử dụng nhiều hơn nhánh chính, bạn có thể muốn tự động đẩy nhánh hiện tại. Hook ( .git/hooks/post-commit) của tôi trông như thế này:

#!/usr/bin/env bash

branch_name=$(git symbolic-ref --short HEAD)
retcode=$?
non_push_suffix="_local"

# Only push if branch_name was found (my be empty if in detached head state)
if [ $retcode -eq 0 ] ; then
    #Only push if branch_name does not end with the non-push suffix
    if [[ $branch_name != *$non_push_suffix ]] ; then
        echo
        echo "**** Pushing current branch $branch_name to origin [i4h post-commit hook]"
        echo
        git push origin $branch_name;
    fi
fi

Nó đẩy nhánh hiện tại, nếu nó có thể xác định tên nhánh bằng git Symbol-ref.

" Cách lấy tên chi nhánh hiện tại trong Git? " Giải quyết vấn đề này và các cách khác để lấy tên chi nhánh hiện tại.

Việc đẩy tự động cho mọi nhánh có thể gây khó chịu khi làm việc trong các nhánh nhiệm vụ nơi bạn mong đợi một số hoạt động tạo xúc xích xảy ra (bạn sẽ không thể dễ dàng rebase sau khi đẩy). Vì vậy hook sẽ không đẩy các nhánh kết thúc bằng một hậu tố xác định (trong ví dụ "_local").


Đối với dòng đầu tiên, tôi phải sử dụng #!/bin/shđể làm cho nó hoạt động. Nếu không nó liên tục nói: error: cannot run .git/hooks/post-commit: No such file or directory. Cảm ơn bạn, tôi thích giải pháp của bạn nhất.
oyalhi

Cảm ơn bạn đã nhận xét, @oyalhi, tôi đã cập nhật dòng shebang trong câu trả lời. Nó sẽ tốt hơn bây giờ!
i4h 19/07/2016

xin chào, tôi gặp lỗi này: .git / hooks / post-commit: dòng 3: EOF không mong muốn trong khi tìm kiếm kết quả phù hợp với `` '.git / hooks / post-commit: dòng 17: lỗi cú pháp: kết thúc tệp không mong muốn
wwwwwwwwwwww

Này, thực sự là có một dấu lùi bị mất. Tôi đã cập nhật câu trả lời, vui lòng thử lại
I4h

9

Tạo một tệp có tên "post-commit" trong thư mục .git / hooks với nội dung là "git push", tuy nhiên, nếu bạn muốn tự động cung cấp mật khẩu, thì bạn sẽ cần phải sửa đổi.


Tôi sẽ ủng hộ câu trả lời của Mark Longair nếu tôi có thể.
Colin R

1
Chờ đã, cái gì? Colin R tại là trong top 2% :)
bài viết tự

3

Tập lệnh git-autopush này cho phép bạn thiết lập một móc hậu cam kết, tương tự như những gì đã được đề xuất trong " Cách định cấu hình đẩy tự động? ".
Nhưng đối với cụm mật khẩu, bạn cần chạy assh-agent .


Không có nhu cầu ssh-agent, chỉ cần sử dụng một cụm từ mật khẩu ít git-only ssh-key: ssh-keygen -t ed25519 -f ~/.ssh/id_pushonly. echo $'\nHost pushonly\nHostname DESTINATION\nIdentityFile ~/.ssh/id_pushonly\n' >> ~/.ssh/config. Trên DESTINATIONcấu hình git-shellnhư được hiển thị trong superuser.com/a/444899/72223 bằng cách sử dụng pubkey từ ~/.ssh/id_pushonly.pub. git-URL cần thiết là một cái gì đó giống như git@pushonly:path/to/repo.git. Để gỡ lỗi: ssh git@pushonly COMMANDphải chạy git-shell -c COMMANDtrên DESTINATION. Để COMMANDxemman git-shell
Tino

@Tino Cảm ơn bạn. Tại sao bạn lại sử dụng lược đồ chữ ký điện tử -t ed25519? Tôi thường sử dụng -t rsa, mặc dù gần đây tôi phải thêm -m PEMvào ssh-keygen( stackoverflow.com/a/53645530/6309 , stackoverflow.com/a/53729009/6309 ).
VonC

@Tino Tôi hiểu rsa chậm hơn, kém an toàn hơn (nếu độ dài của nó thấp hơn 2048 bit: bagja.net/blog/upgrade-ssh-key-to-ed25519.html ), nhưng tôi xử lý công việc với các máy chủ openssh cũ hơn có thể không diễn giải chính xác chữ ký ed255519.
VonC

Tôi chủ yếu sử dụng ed25519vì nó cung cấp các dòng ngắn và tiện dụng cho ~/.ssh/authorized_keys. Ngoài ra, điều mà DJB viết về ed255519 rất thú vị là : Bảo mật chống lại các kênh bên (Spectre), ít CPU hơn, v.v. BTW, khi xử lý sshdcác s cũ , tôi thường tạo một khóa đặc biệt cho chúng và sau đó cấu hình điều này trong ~/.ssh/config.
Tino

0

Đây là hướng dẫn đơn giản để đẩy / kéo mà không cần cung cấp cụm mật khẩu qua ssh cho những người sử dụng Linux và Windows (git bash)

Về khách hàng của bạn:

  1. Kiểm tra xem bạn đã tạo khóa ssh chưa:

    $ ls ~/.ssh/id_rsa.pub; ls ~/.ssh/id_dsa.pub
    /c/Users/Cermo/.ssh/id_rsa.pub  <-- I have RSA key
    ls: cannot access '/c/Users/Cermo/.ssh/id_dsa.pub': No such file or directory
    
  2. Nếu bạn không có bất kỳ khóa nào (hai dòng "ls: không thể truy cập ..."), hãy tạo một khóa mới. Nếu bạn có bất kỳ phím nào, hãy bỏ qua bước này.

    $ ssh-keygen.exe
    Generating public/private rsa key pair.
    Enter file in which to save the key (/c/Users/Cermo/.ssh/id_rsa):
    Enter passphrase (empty for no passphrase): <-- press Enter
    Enter same passphrase again: <-- press Enter
    
  3. Sao chép khóa của bạn vào máy chủ từ xa mà bạn muốn kéo hoặc đẩy bằng git:

    $ ssh-copy-id user_name@server_name
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to 
    filter out any that are already installed
    /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you 
    are prompted now it is to install the new keys
    user_name@server_name's password:
    
    Number of key(s) added: 1
    
    Now try logging into the machine, with:   "ssh 'user_name@server_name'"
    and check to make sure that only the key(s) you wanted were added.
    

Lưu ý: Bạn sẽ phải cung cấp mật khẩu trong quá trình hoạt động này. Sau đó, các hoạt động kéo / đẩy của bạn sẽ không yêu cầu mật khẩu.

Lưu ý 2: Bạn phải đăng nhập vào máy chủ bằng user_name ít nhất một lần trước khi sử dụng quy trình này (thư mục chính mà các khóa ssh được sao chép được tạo trong lần đăng nhập đầu tiên)


0

Đây là tập lệnh bash để git tự động pushđến repo từ xa

  1. Tự động kiểm tra ssh-agent
  2. Tự động gửi cụm mật khẩu bằng tập lệnh mong đợi
  3. Cách sử dụng đơn giản là: $ cd /path/to/your/repositorysau đó$ push

Đặt tập lệnh này vào một tệp chẳng hạn $HOME/.ssh/push

#!/bin/bash

# Check connection
ssh-add -l &>/dev/null
[[ "$?" == 2 ]] && eval `ssh-agent` > /dev/null

# Check if git config is configured
if [ ! $(git config user.name) ]
then 
    git config --global user.name <user_name>
    git config --global user.email <user_email>
fi

# Check if expect is installed
if [[ ! $(dpkg -l | grep expect) ]]
then 
    apt-get update > /dev/null
    apt-get install --assume-yes --no-install-recommends apt-utils expect > /dev/null
fi

# Check identity
ssh-add -l &>/dev/null
[[ "$?" == 1 ]] && expect $HOME/.ssh/agent > /dev/null

# Clean and push repo
REMOTE=$(git remote get-url origin)
URL=git@github.com:${REMOTE##*github.com/}
[[ $REMOTE == "http"* ]] && git remote set-url origin $URL
git add . && git commit -m "test automatically push to a remote repo"
git status && git push origin $(git rev-parse --abbrev-ref HEAD) --force

Liên kết nó với /binthư mục để nó có thể được gọi bằng $ pushlệnh

$ sudo ln -s $HOME/.ssh/push /bin/push
$ chmod +x /bin/push

0

Nếu bạn đang sử dụng Husky, nó sẽ ghi đè post-committệp hooks của bạn theo mặc định.

Chúng tôi đang sử dụng lệnh này trong package.json để tự động rebase-và đẩy mọi cam kết thành master. (Lần chạy đầu tiên yarn add --dev git-branch-is.)

  "husky": {
    "hooks": {
     "post-commit": "git-branch-is master && git rebase origin master && git push origin master"`
    }
  }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.