Różnice między poleceniami „git pull” podczas pobierania ze źródła?

82

Jakie są różnice między tymi poleceniami ?:

# 1
git pull
# 2
git pull origin
# 3
git pull origin master
# 4
git pull origin/master
# 5
git pull origin HEAD:master
Ben Gao
źródło
Cóż, nawet po przeczytaniu strony podręcznika, nie we wszystkich przypadkach jest jasne, co dokładnie się wydarzy. Na przykład: jakie jest znaczenie git pullbez skonfigurowanego upstream? (Strona podręcznika podaje tylko, że domyślnie jest to skonfigurowany nadrzędny.)
michas
W skrócie: 1. zakończy się niepowodzeniem bez konfiguracji dla bieżącej gałęzi, a poza tym będzie wyglądał jak 2. z nazwą zdalną. 2. użyje domyślnych konfiguracji pobierania dla danego pilota (i połączy pierwszy), podczas gdy w 3. określisz, co pobierać i łączyć. 4. jest nieważne, imho. 5. (jeśli to działa), umieści zdalną HEAD w refs / remotes / origin / master i połączy to.
andi5
2
Głosowanie za ponownym otwarciem tego pytania, ponieważ niestety jest to jeden z wyników wyszukiwania dla site:stackoverflow.com git Difference "git pull" "git pull origin master".

Odpowiedzi:

81

git pullto wygodna komenda, która polega na robieniu różnych rzeczy w tym samym czasie. Zasadniczo jest to po prostu połączenie git fetch, które łączy się ze zdalnym repozytorium i pobiera nowe zatwierdzenia i git merge(lub git rebase) włącza nowe zatwierdzenia do lokalnego oddziału. Ze względu na dwa różne polecenia znaczenie słowa git pullnie zawsze jest oczywiste.

Możesz skonfigurować upstream dla lokalnego oddziału. Po świeżym klonie będziesz miał lokalną gałąź "master", zdalny "początek", a twoja gałąź główna będzie miała "początek / wzorzec" jako nadrzędny. Zakładam tę konfigurację poniżej. (Możesz zobaczyć swoją konfigurację nadrzędną za pomocą git branch -vvlub patrząc na .git / config.)

Teraz na twoje pytania:

  1. git pull= git fetch origin+ git merge origin/master(lub czymkolwiek jest twój upstream)
  2. git pull origin= git pull(o ile źródło jest Twoim pilotem)
  3. git pull origin master= git fetch origin master+git merge FETCH_HEAD
  4. git pull origin/master : niepoprawne, chyba że masz pilota o nazwie „origin / master”
  5. git pull origin HEAD:master: Próbuje bezpośrednio zresetować twojego lokalnego mastera do dowolnego HEAD wskazującego na początek. (Nie rób tego.)
michas
źródło
2
Dlaczego wykonanie git pull origin HEAD:masterzłego pomysłu?
Ryan Edwards
2
Prawa strona ma być oddziałem zdalnym. Zobacz ostrzeżenie na stronie podręcznika. Upewnij się, że wiesz, co robisz, jeśli tego używasz.
michas
gdybym był w git pull
jakiejś innej
1
@aWebDeveloper: Dla kompletności: git pull origin HEAD:masterzasadniczo (było dosłownie do czasu przepisania skryptu w C w Git 2.6) przekazuje HEAD:masterczęść do git fetch, więc robi to, co git fetchrobi dla tego kroku; następnie scala lub ponownie bazuje za pomocą skrótu zatwierdzenia, który git fetchotrzymał krok. Refspecs to source: dest , więc HEADjest przekazywane innemu Gitowi do przetłumaczenia. Więc to zależy od innego Gita - ale zwykle inny Git HEADto jego nazwa master. Jeśli nie jesteś sam master, funkcja scalania lub rebase używa zaktualizowanego pobierania master( dest ) (chyba że się fetchnie powiedzie).
torek
1
Jeszcze jedna rzecz, na którą należy uważać: nigdy nie rób git pull origin br1 br2. Wygląda i wydaje się, że powinno git checkout br1; git pull origin; git checkout br2; git pull origin- ale tak nie jest! Zamiast tego w efekcie robi git fetch origin && git merge origin/br1 origin/br2:, co łączy oba wyniki pobierania z aktualną gałęzią, coś, co Git nazywa scaleniem ośmiornicy . Nigdy tego nikt nie chce. Prawdopodobnie git pullpowinien całkowicie odrzucić polecenie (każdy, kto naprawdę tego chce, może najpierw uruchomić pobieranie, a następnie scalanie).
torek
18

A pullto w zasadzie a fetch(które pobiera pewne zatwierdzenia i powiązane obiekty ze zdalnego repozytorium do twojego), a następnie operacja, która „stosuje” je do twojej kopii roboczej. Drugi etap jest domyślnie wykonywany za pomocą a, mergeale możesz ustawić pull.rebasezmienną na, truea zamiast tego zostanie ponownie ustawiona .

W poleceniu pojawiają się dwa pytania pull. Po pierwsze, co dokładnie jest pobierane? A po drugie, w jaki sposób stosuje te zmiany do mojej kopii roboczej? Zacznijmy od pierwszego. Pełna forma polecenia to

git pull [options] [repository] [<refspec>...]

optionsSą flagi, które zachowanie sterowania (np --rebase aby uczynić pullpracę jako fetch+ rebasenawet jeśli pull.rebasejest false).

repository to nazwa (lub adres URL) pilota, z którego ma zostać pobrane.

refspecs są zwięzłym sposobem określenia, które odniesienia na pilocie chcesz pobrać i gdzie chcesz je umieścić w bieżącej kopii roboczej.

Przyjmijmy najpierw najbardziej wyraźną formę.

 git pull origin branch1:branch2

Zasadniczo mówi to, ściągnij zmiany w odwołaniu branch1na zdalnym wywołaniu, origina następnie scal je (lub ponownie bazuj) w lokalnym oddziale branch2. Jeśli na przykład powiem git pull origin master:dev, otrzymam wywoływaną gałąź lokalną, devktóra będzie wskazywać na to samo zatwierdzenie co master. Szczegóły dotyczące określania refspecs znajdują się tutaj . Możesz użyć a, *aby wskazać wiele refspecs. Na przykład, git pull origin refs/heads/*:refs/heads/*ściągnie wszystkie gałęzie (przechowywane w heads) do lokalnego repozytorium i połączy je w lokalne gałęzie o tych samych nazwach.

Teraz usuńmy argumenty jeden po drugim, aby omówić działanie domyślne. Najpierw możemy usunąć miejsce docelowe z naszego refspec i po prostu powiedzieć git pull origin branch1. Spowoduje to najpierw fetchprzeniesienie zdalnej gałęzi branch1do lokalnego repozytorium. Będzie dostępny jako tymczasowe odniesienie o nazwie FETCH_HEAD. Następnie uruchomi się, git merge FETCH_HEADco spowoduje połączenie tej gałęzi z bieżącą aktywną gałęzią (tj HEAD.). Jest to często wykonywane, gdy jesteś w lokalnym oddziale i chcesz pobrać zmiany ze zdalnego do tego oddziału.

Porzućmy teraz branch1całkowicie i po prostu powiedz git pull origin. Teraz git wie, skąd pobrać ( origin), ale nie wie, co pobrać. Ma do tego pewne wartości domyślne. Najbardziej scenariusz to sytuacja, w której plik konfiguracyjny ma branch.<name>.mergeopcję (jest to wpis o nazwie mergewewnątrz sekcji takiej jak [branch "master"]). Jeśli tak, użyje tamtejszych refspecs do operacji.

Jeśli porzucimy origincałkowicie i po prostu powiemy git pull, sprawdzi konfigurację, aby zobaczyć, czy istnieje, branch.<name>.remotektóry określa, z którego pilota pobrać. To wraz z powyższym mówi ci, co ciągnąć.

Twoje punkty # 4 i # 5 nie są normalnymi przypadkami użycia. Pierwsza ma sens, jeśli masz połączenie zdalne, origin/masterco jest mało prawdopodobne. origin/masterjest zwykle lokalną referencją, która śledzi mastergałąź na pilocie origin. Drugi spróbuje pobrać zmiany na HEADzdalnym (domyślna gałąź, która zwykle jest master), a następnie scalić je z lokalnym master. Chociaż może to być coś, co chcesz robić regularnie, polecenie jest dość niekonwencjonalne i nie jest często używane.

Pominąłem kilka szczegółów, ale te powinny wystarczyć, aby zapewnić Ci bezpieczeństwo i wygodę w codziennej pracy. Wszystkie krwawe szczegóły można znaleźć na stronie podręcznika git pull.

Noufal Ibrahim
źródło
„Jeśli na przykład powiem git pull origin master: dev, otrzymam lokalną gałąź o nazwie dev, która będzie wskazywać na to samo zatwierdzenie co master”. Więc pobrałbyś nową gałąź o nazwie dev i wskazywałaby na master?
user33276346
Nie, możesz pobrać gałąź masterz pilota, ale zostanie wywołana devlokalnie.
Noufal Ibrahim
git pull origin refs/heads/*:refs/heads/*nie działa dla mnie i mam no matches found: refs/heads/*:refs/heads/*. Też próbowałem git pull origin refs/remotes/origin/*:refs/heads/*, ale to też nie działało. Nie sądzę, by możliwe było ściągnięcie wszystkich gałęzi na odległość za pomocą jednego polecenia, podobnie jak późniejsze scalanie / ponowne bazowanie wszystkich tych gałęzi na ich kolejne gałęzie lokalne.
Ben Butterworth,