Jak automatycznie pushować po zatwierdzeniu w git?


86

Jak ustawić git na automatyczne wypychanie do zdalnego repozytorium (w tym automatyczne dostarczanie mojego hasła) po każdym zatwierdzeniu do lokalnego repozytorium?


1
Jaki protokół przepychasz? Jeśli prosi o hasło, zakładam, że jest to SSH lub HTTP.
Mark Longair,

1
W przypadku pytań dotyczących gita zawsze pomocne jest przynajmniej wspomnienie, jakiego systemu operacyjnego używasz.
Mark Longair

1
Kwestionuję mądrość takiej konfiguracji. To eliminuje możliwość reorganizacji twoich zmian w inny zestaw zatwierdzeń (szczególnie rebasing). Popełniam zbyt wiele błędów, żeby taka konfiguracja była dla mnie przydatna.
jpmc26

Odpowiedzi:


141

Najpierw upewnij się, że możesz wysłać ręcznie bez podawania hasła. Jeśli przesyłasz przez HTTP lub HTTPS, będzie to przypadek utworzenia .netrcpliku z danymi logowania lub dodania nazwy użytkownika i hasła do adresu URL pilota . Jeśli używasz protokołu SSH, możesz utworzyć parę kluczy, w której klucz prywatny nie ma hasła, lub użyć go ssh-agentdo buforowania klucza prywatnego .

Następnie powinieneś utworzyć plik wykonywalny ( chmod +x) .git/hooks/post-commitzawierający następujące elementy:

#!/bin/sh
git push origin master

... dostosowywanie tej linii, jeśli chcesz wysłać do pilota innego niż originlub wypchnąć gałąź inną niż master. Upewnij się, że ten plik jest wykonywalny.


3
Nie można zmusić ssh-agent do zapamiętania mojego hasła, więc musiałem je opróżnić. Mam nadzieję, że moja żona nie włamie się na moje konto :)
ulu

Mówiąc o dostosowywaniu, co jeśli chcę przesunąć niektóre, ale nie wszystkie gałęzie w ten sposób? Na przykład chcę automatycznie wypychać tylko te gałęzie, które mają odpowiednią gałąź zdalną zanotowaną w .git/configprefiksie feature/xy/.
Acumenus

5
git push - all origin
Yada

4
chmod + x .git / hooks / post-commit
UnchartedWorks

33

Jeśli zaczniesz używać więcej niż gałęzi głównej, możesz chcieć automatycznie wypchnąć bieżącą gałąź. Mój hook ( .git/hooks/post-commit) wygląda tak:

#!/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

Przesuwa aktualną gałąź, jeśli może określić nazwę gałęzi za pomocą git symbolic-ref.

Jak uzyskać nazwę aktualnej gałęzi w Git? ” Dotyczy tego i innych sposobów uzyskania aktualnej nazwy gałęzi.

Automatyczne wypychanie każdej gałęzi może przeszkadzać podczas pracy w gałęziach zadaniowych, w których spodziewasz się zrobienia kiełbasy (nie będziesz w stanie łatwo zmienić bazy po pchnięciu). Zatem hak nie będzie przepychał gałęzi kończących się zdefiniowanym sufiksem (w przykładzie „_local”).


W przypadku pierwszej linii musiałem użyć, #!/bin/shaby to zadziałało. W przeciwnym razie to powtarzał: error: cannot run .git/hooks/post-commit: No such file or directory. Dziękuję, najbardziej podoba mi się Twoje rozwiązanie.
oyalhi

Dziękuję za komentarz, @oyalhi, zaktualizowałem linię shebang w odpowiedzi. Teraz powinno lepiej portować!
i4h

witam, otrzymuję ten błąd: .git / hooks / post-commit: line 3: nieoczekiwany EOF podczas szukania pasującego `` '' .git / hooks / post-commit: wiersz 17: błąd składni: nieoczekiwany koniec pliku
Tobias

Hej, rzeczywiście był zagubiony backtick. Zaktualizowałem odpowiedź, spróbuj ponownie
i4h

9

Utwórz plik o nazwie „post-commit” w katalogu .git / hooks z zawartością „git push”, chociaż jeśli chcesz automatycznie podać hasło, konieczna będzie modyfikacja.


Głosowałbym za odpowiedzią Marka Longaira, gdybym mógł.
Colin R

1
Czekaj, co? Colin R jest teraz w czołówce 2% :)
Opublikuj samodzielnie

3

Ten skrypt git-autopush umożliwia ustawienie przechwytywania po zatwierdzeniu, podobnie do tego, co zostało zalecane w sekcjiJak skonfigurować automatyczne przekazywanie? ”.
Ale w przypadku hasła musisz uruchomić plikssh-agent .


Nie ma potrzeby ssh-agent, wystarczy użyć innego hasła mniej git-tylko ssh-klawisz: ssh-keygen -t ed25519 -f ~/.ssh/id_pushonly. echo $'\nHost pushonly\nHostname DESTINATION\nIdentityFile ~/.ssh/id_pushonly\n' >> ~/.ssh/config. Podczas DESTINATIONkonfiguracji, git-shelljak pokazano na superuser.com/a/444899/72223 przy użyciu klucza pubkey z ~/.ssh/id_pushonly.pub. Potrzebny git-URL to coś w stylu git@pushonly:path/to/repo.git. Do debugowania: ssh git@pushonly COMMANDmusi działać git-shell -c COMMANDna DESTINATION. Do COMMANDzobaczeniaman git-shell
Tino

@Tino Dziękuję. Dlaczego używasz schematu podpisu cyfrowego -t ed25519? Używam ogólnie -t rsa, choć ostatnio muszę dodać -m PEMdo ssh-keygen( stackoverflow.com/a/53645530/6309 , stackoverflow.com/a/53729009/6309 ).
VonC

@Tino Rozumiem, że rsa jest wolniejszy, mniej bezpieczny (jeśli jego długość jest mniejsza niż 2048 bitów: bagja.net/blog/upgrade-ssh-key-to-ed25519.html ), ale mam do czynienia ze starszymi serwerami openssh, które mogą niepoprawnie interpretuje podpis ed255519.
VonC

Używam przede wszystkim ed25519dlatego, że daje krótkie i poręczne linki ~/.ssh/authorized_keys. Bardzo interesujące jest również to, co DJB pisze o ed255519 : Zabezpieczenie przed kanałami bocznymi (Spectre), mniej procesora itp. Przy okazji, gdy sshdmam do czynienia ze starymi s, zwykle tworzę dla nich specjalny klucz i konfiguruję go w ~/.ssh/config.
Tino

0

Oto prosta instrukcja wypychania / wyciągania bez podawania hasła przez ssh dla osób używających Linuksa i Windowsa (git bash)

Na Twoim kliencie:

  1. Sprawdź, czy masz wygenerowane klucze ssh:

    $ 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. Jeśli nie masz żadnego klucza (dwie linie „ls: cannot access ...”), wygeneruj nowy. Jeśli masz któryś z kluczy, pomiń ten krok.

    $ 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. Skopiuj swój klucz na zdalny serwer, z którego chcesz pobrać lub wypchnąć za pomocą 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.
    

Uwaga: podczas tej operacji będziesz musiał podać hasło. Po tym twoje operacje pull / push nie będą żądać hasła.

Uwaga 2: Musisz zalogować się do serwera używając nazwa_użytkownika przynajmniej raz przed użyciem tej procedury (katalog domowy, do którego kopiowane są klucze ssh jest tworzony podczas pierwszego logowania)


0

Oto skrypt bash dla gita, który automatycznie przenosi się pushdo zdalnego repozytorium

  1. Automatycznie sprawdzaj ssh-agent
  2. Automatycznie wysyłaj hasło za pomocą skryptu oczekiwania
  3. Użycie jest po prostu: $ cd /path/to/your/repositorywtedy$ push

Umieść ten skrypt na przykład w pliku $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

Połącz go z /binkatalogiem, aby można go było wywołać za pomocą $ pushpolecenia

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

0

Jeśli używasz Husky, post-commitdomyślnie nadpisze plik hooks.

Używamy tego polecenia w package.json, aby automatycznie zmienić bazę i wypchnąć wszystkie zatwierdzenia do mastera. (Pierwszy bieg yarn add --dev git-branch-is.)

  "husky": {
    "hooks": {
     "post-commit": "git-branch-is master && git rebase origin master && git push origin master"`
    }
  }
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.