Co oznacza fetch HEAD w Git?

git pull --help says:

W domyślnym trybie, git pull jest skrótem od git fetch, a następnie Git merge fetch_head.

Co to jest FETCH_HEAD, a co jest faktycznie połączone podczas git pull?

 166
Author: Charles, 2012-02-11

5 answers

FETCH_HEAD jest krótkotrwałym ref, aby śledzić to, co właśnie zostało pobrane ze zdalnego repozytorium. git pull najpierw wywołuje git fetch, w normalnych przypadkach pobiera gałąź z pilota; FETCH_HEAD wskazuje na końcówkę tej gałęzi (przechowuje ona SHA1 commita, tak jak gałęzie to robią). git pull następnie wywołuje git merge, scalając FETCH_HEAD do bieżącej gałęzi.

Wynik jest dokładnie tym, czego można się spodziewać: commit na końcu odpowiedniej zdalnej gałęzi zostanie scalony z commitem na końcu Twój obecny oddział.

Jest to trochę jak robienie git fetch bez argumentów (lub git remote update), aktualizowanie wszystkich zdalnych gałęzi, a następnie uruchamianie git merge origin/<branch>, ale używanie FETCH_HEAD wewnętrznie zamiast odwoływania się do każdego z pobranych referencji, zamiast konieczności nazywania rzeczy.

 168
Author: Cascabel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-11 03:18:17

FETCH_HEAD jest odniesieniem do końcówki ostatniego pobierania, niezależnie od tego, czy pobieranie zostało zainicjowane bezpośrednio za pomocą polecenia fetch, czy jako część pull. Bieżąca wartość FETCH_HEAD jest przechowywana w folderze .git w pliku o nazwie FETCH_HEAD.

Więc jeśli wydam:

git fetch https://github.com/ryanmaxwell/Fragaria

FETCH_HEAD może zawierać

3cfda7cfdcf9fb78b44d991f8470df56723658d3        https://github.com/ryanmaxwell/Fragaria

Jeśli mam zdalne repo skonfigurowane jako zdalna gałąź śledzenia, mogę śledzić moje pobieranie z scaleniem gałęzi śledzenia. Jeśli nie mogę połączyć końcówka ostatniego pobierania bezpośrednio przy użyciu FETCH_HEAD.

git merge FETCH_HEAD
 15
Author: Jonathan Mitchell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-31 01:02:55

Właśnie odkryłem i użyłem FETCH_HEAD. Chciałem lokalną kopię jakiegoś oprogramowania z serwera i zrobiłem

git fetch gitserver release_1

gitserver to nazwa mojej maszyny, która przechowuje repozytoria Gita. {[6] } jest tagiem dla wersji oprogramowania. Ku mojemu zdziwieniu, release_1 nie było wtedy nigdzie w mojej lokalnej maszynie. Musiałem wpisać

 git tag release_1 FETCH_HEAD 

Aby uzupełnić kopię tagged łańcuch zobowiązań (release_1) ze zdalnego repozytorium do lokalnego. Fetch znalazł remote tag, skopiował commit na moją lokalną maszynę, nie stworzył lokalnego znacznika, ale ustawiłFETCH_HEAD na wartość commita, abym mógł go znaleźć i użyć. Następnie użyłem FETCH_HEAD do utworzenia lokalnego znacznika, który pasował do znacznika na zdalnym. Jest to praktyczna ilustracja tego, czym jest FETCH_HEAD i jak można go używać, i może być przydatna dla kogoś, kto zastanawia się, dlaczego git fetch nie robi tego, czego ty naiwnie oczekujesz.

Moim zdaniem najlepiej w tym celu unikać i lepszym sposobem na osiągnięcie tego, co próbowałem zrobić, jest

git fetch gitserver release_1:release_1

Czyli pobrać release_1 i wywołać lokalnie release_1. (Źródło: dest, zobacz https://git-scm.com/book/en/v2/Git-Internals-The-Refspec ; na wypadek, gdybyś chciał nadać mu inną nazwę!)

Możesz czasem użyć FETCH_HEAD: -

git fetch gitserver bugfix1234
git cherry-pick FETCH_HEAD

Może to być dobry sposób na użycie poprawki 1234 z serwera Git, i pozostawienie garbage collection Git, aby pozbyć się kopii z serwera gdy poprawka zostanie pobrana na bieżącą gałąź. (Zakładam, że istnieje ładny, czysty tagowany commit zawierający całą poprawkę błędu na serwerze!)

 7
Author: user3070485,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-26 10:25:35

Jak wspomniano w odpowiedzi Jonathana, FETCH_HEAD odpowiada plikowi .git/FETCH_HEAD. Zazwyczaj plik będzie wyglądał tak:

71f026561ddb57063681109aadd0de5bac26ada9                        branch 'some-branch' of <remote URL>
669980e32769626587c5f3c45334fb81e5f44c34        not-for-merge   branch 'some-other-branch' of <remote URL>
b858c89278ab1469c71340eef8cf38cc4ef03fed        not-for-merge   branch 'yet-some-other-branch' of <remote URL>

Zauważ jak wszystkie gałęzie oprócz jednej są zaznaczone not-for-merge. Dziwna jest gałąź, która została sprawdzona przed aportem. Podsumowując: fetch_head zasadniczo odpowiada zdalnej wersji gałęzi, która jest aktualnie sprawdzana.

 6
Author: Carsten Führmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-07 09:36:49

Git pull jest kombinacją fetch, a następnie merge. Gdy zdarzy się git fetch, notuje commit head tego, co zostało pobrane w FETCH_HEAD (tylko plik o tej nazwie w .git) i te commity są następnie scalane do twojego katalogu roboczego.

 2
Author: manojlds,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-11 02:45:03