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?

ulu
źródło
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.

Mark Longair
źródło
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”).

i4h
źródło
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.

Colin R.
źródło
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 .

VonC
źródło
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)

Rafał Gnitecki
źródło
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)
[email protected]:${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
Chetabahana
źródło
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"`
    }
  }
Freewalker
źródło