Wybór tylko jednej gałęzi: fetch
/ merge
vs. pull
Ludzie często radzą ci oddzielić „pobieranie” od „scalania”. Zamiast tego mówią:
git pull remoteR branchB
Zrób to:
git fetch remoteR
git merge remoteR branchB
Nie wspominają o tym, że takie polecenie pobierania faktycznie pobierze wszystkie gałęzie ze zdalnego repozytorium, co nie jest tym, co robi to polecenie pull. Jeśli masz tysiące oddziałów w zdalnym repozytorium, ale nie chcesz widzieć ich wszystkich, możesz uruchomić to niejasne polecenie:
git fetch remoteR refs/heads/branchB:refs/remotes/remoteR/branchB
git branch -a # to verify
git branch -t branchB remoteR/branchB
Oczywiście jest to absurdalnie trudne do zapamiętania, więc jeśli naprawdę chcesz uniknąć pobierania wszystkich gałęzi, lepiej zmienić swoje, .git/config
jak opisano w ProGit.
Co?
Najlepsze wyjaśnienie tego wszystkiego znajduje się w rozdziale 9-5 programu ProGit, Git Internals - The Refspec ( lub przez github ). To niezwykle trudne do znalezienia w Google.
Najpierw musimy wyjaśnić pewną terminologię. W przypadku śledzenia oddziałów zdalnych istnieją zazwyczaj 3 różne gałęzie, o których należy pamiętać:
- Gałąź w repozytorium zdalnym:
refs/heads/branchB
wewnątrz drugiego repozytorium
- Twoja gałąź zdalnego śledzenia :
refs/remotes/remoteR/branchB
w Twoim repozytorium
- Twój własny oddział:
refs/heads/branchB
wewnątrz swojej repo
Gałęzie zdalnego śledzenia (in refs/remotes
) są tylko do odczytu. Nie modyfikujesz ich bezpośrednio. Modyfikujesz własną gałąź, a następnie wypychasz ją do odpowiedniej gałęzi w zdalnym repozytorium. Wynik nie jest odzwierciedlany w twoim, refs/remotes
dopóki nie nastąpi odpowiednie wyciągnięcie lub pobranie. To rozróżnienie było dla mnie trudne do zrozumienia na podstawie stron podręcznika git, głównie dlatego, że lokalna gałąź ( refs/heads/branchB
) "śledzi" gałąź zdalnego śledzenia podczas .git/config
definiowania branch.branchB.remote = remoteR
.
Pomyśl o „referencjach” jak o wskaźnikach C ++. Fizycznie są to pliki zawierające skróty SHA, ale w zasadzie są tylko wskaźnikami do drzewa zatwierdzeń. git fetch
doda wiele węzłów do twojego drzewa zatwierdzeń, ale to, jak git decyduje, które wskaźniki przenieść, jest nieco skomplikowane.
Jak wspomniano w innej odpowiedzi , też nie
git pull remoteR branchB
ani
git fetch remoteR branchB
ruszyłby się refs/remotes/branches/branchB
, a ten drugi z pewnością nie może się poruszyć refs/heads/branchB
. Jednak obaj się ruszają FETCH_HEAD
. (Można cat
każdy z tych plików wewnątrz .git/
, aby zobaczyć, kiedy się zmieniają.) I git merge
będzie odnosić się do FETCH_HEAD
, natomiast ustawienie MERGE_ORIG
, etc.
git fetch origin an-other-branch
przechowuje pobraną wskazówkęFETCH_HEAD
, ale nieorigin/an-other-branch
(tj. Zwykła „gałąź zdalnego śledzenia”). Można by to zrobićgit fetch origin an-other-branch && git merge FETCH_HEAD
, ale robienie tego tak, jak mówi @Gareth, jest lepsze (lub po prostu użyj git pull ).