Що означає FETCH_HEAD в Git?


221

git pull --help каже:

У режимі за замовчуванням git pullце стенограма, за git fetchякою слід git merge FETCH_HEAD.

Що це таке FETCH_HEADі що насправді зливається протягом git pull?


3
Примітка: оскільки git 1.8.4 (серпень 2013 року) git fetch origin masterфактично оновиться origin/master, а не лише FETCH_HEAD. Див stackoverflow.com/a/20967347/6309
VonC

Більш детальну інформацію про git merge FETCH_HEAD(з Git 2.5, Q2 2015), см stackoverflow.com/a/30425991/6309
VonC

Відповіді:


218

FETCH_HEADце недовговічна інформація, щоб відслідковувати щойно отримане з віддаленого сховища. git pullспочатку викликає git fetch, у звичайних випадках дістаючи гілку з віддаленого; FETCH_HEADвказує на кінчик цієї гілки (вона зберігає SHA1 комітету так само, як це роблять гілки). git pullпотім викликає git merge, об'єднуючись FETCH_HEADу поточну гілку.

Результат - саме те, що ви очікували: фіксація на вершині відповідної віддаленої гілки об'єднується в коміт на кінчику вашої поточної гілки.

Це трохи схоже на те, що можна робити git fetchбез аргументів (або git remote update), оновлювати всі віддалені гілки, потім запускати git merge origin/<branch>, але використовуючи FETCH_HEADвнутрішньо, а не для того, щоб посилатися на будь-який отриманий посилання, замість того, щоб називати речі.


9
@Jefromi: вибачте, я думаю , ви не праві: наскільки я розумію, git fetchоновлення (Злиття) всі дані об'єкта з віддаленого сховища, а не тільки на бранч. Тож я не розумію з вашої відповіді, як git вирішує на кінчик якої гілки вказати FETCH_HEAD. Я також не можу знайти FETCH_HEADв git документації (визначення, а не приклади). Існування FETCH_HEADвиглядає на мене більше як на вирішення проблеми, щоб якось зробити git pullроботу .
Олексій

14
Олексій: FETCH_HEADвідповідає кінчику віддаленої гілки, вказаному branch.<BRANCH>.mergeв конфігурації локального сховища. Отже, хоча fetchдійсно отримує всі об’єктні дані з віддаленого сховища, FETCH_HEADвін використовується для вказівки того, куди просунулася віддалена гілка, відслідкована місцевою гілкою. Тож якщо ви перебуваєте на локальній masterгілці та біжите git fetchта branch.master.mergeвказуєте на refs/heads/master, то FETCH_HEADматимете те саме значення, що й origin/masterодразу після операції отримання.
larsks

4
@alexy FETCH_HEAD описаний у другому параграфі опису git fetch на його довідковій сторінці. Моя відповідь правильна. І git fetch без аргументів оновлює всі віддалені гілки для віддаленого за замовчуванням ... але це, безумовно, не те саме, що об'єднання.
Каскабель

4
Що робити, FETCH_HEADякщо ви отримаєте всі віддалені гілки через git fetch -a?
стигі

2
@stigi Підказка віддаленої гілки відстеження, на яку ви в даний час оглядаєте гілку, вказує в git config. Будь ласка, дивіться відповідь ларок у коментарі вище.
Ankur Agarwal

19

FETCH_HEAD - це посилання на підказку останнього вибору, незалежно від того, чи був цей ініціюваний безпосередньо за допомогою команди fetch, або як частина витягування. Поточне значення FETCH_HEAD зберігається в .gitпапці у файлі з іменем, ви вже здогадалися, FETCH_HEAD.

Тож якщо я видаю:

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

FETCH_HEAD може містити

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

Якщо у мене віддалене репо налаштоване як гілка віддаленого відстеження, я можу прослідкувати за моїм результатом злиття гілки відстеження. Якщо я цього не роблю, я можу з’єднати кінчик останнього вибору безпосередньо за допомогою FETCH_HEAD.

git merge FETCH_HEAD

1
Щоб додати мої 5 центів. Що мене збентежило, це те, що мій FETCH_HEAD був позаду останніх доручень, навіть якщо робив новий збір, який повернув "без змін" (у затемненні). Я думаю, що причина полягає в тому, що всі зміни з мого останнього результату були від мене самій і мене відтіснили на сервер. Тож подальший збір не мав нічого робити і навіть не оновлював FETCH_HEAD. Я не впевнений, чи це недолік реалізації GIT чи Eclipse Git.
Torge

11

Як було сказано у відповіді Джонатана , файл FETCH_HEAD відповідає файлу .git/FETCH_HEAD. Зазвичай файл буде виглядати приблизно так:

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>

Зверніть увагу, як маркуються всі гілки, окрім однієї not-for-merge. Непарною є гілка, яку перевірили перед початком. Підсумовуючи це: FETCH_HEAD по суті відповідає віддаленій версії гілки, яка зараз перевірена.


9

Я щойно відкрив і використовував FETCH_HEAD. Я хотів локальну копію деякого програмного забезпечення з сервера, і я це зробив

git fetch gitserver release_1

gitserver- це назва моєї машини, яка зберігає сховища git. release_1є тегом для версії програмного забезпечення. На мій подив, release_1тоді ніде не було знайдено моєї локальної машини. Мені довелося набрати

 git tag release_1 FETCH_HEAD 

для завершення копії позначеного ланцюжка комітетів (release_1) з віддаленого сховища до локального. Fetch знайшов віддалений тег, скопіював команду на мою локальну машину, не став створив локальний тег, але встановив FETCH_HEADзначення фіксації, щоб я міг його знайти та використовувати. Потім я FETCH_HEADстворив локальний тег, який відповідав би тегу на пульті. Це практична ілюстрація того, що FETCH_HEADє і як це можна використовувати, і може бути корисним іншим, хто цікавиться, чому git fetch не робить того, чого ви наївно очікували.

На мою думку, найкраще уникати цієї мети, і кращий спосіб досягти того, що я намагався зробити

git fetch gitserver release_1:release_1

тобто вивести release_1 і називати його випуском_1 локально. (Це джерело: dest, див Https://git-scm.com/book/en/v2/Git-Internals-The-Refspec ; про всяк випадок, якщо ви хочете дати йому інше ім’я!)

Ви можете використовувати час FETCH_HEADвід часу: -

git fetch gitserver bugfix1234
git cherry-pick FETCH_HEAD

може бути хорошим способом використання виправлення помилок 1234 з вашого сервера Git, а також залишаючи Git зібрання сміття, щоб утилізувати копію з сервера, як тільки виправлення було вибрано вишнею на вашій поточній гілці. (Я припускаю, що на сервері є хороший чистий тег, який містить цілу помилку виправлення!)


Цікаві відгуки. +1
VonC

Дякую. Я редагував свій оригінальний пост, написаний, коли я вперше виявив FETCH_HEAD пару років тому, оскільки, здається, він заохочує скопіювати тег за допомогою FETCH_HEAD, а не джерело: синтаксис dest для refspecs. Сподіваюсь, я зараз подав кращий приклад того, як можна використовувати FETCH_HEAD.
Іван

3

git pull - це поєднання вибору з подальшим злиттям. Коли git fetch трапляється, він зазначає, що головна фіксація того, що він отримав у FETCH_HEAD (просто файл із таким ім'ям у .git), і ці комісії потім об'єднуються у вашу робочу директорію.


3
@manjolds, що ти маєш на увазі під " головою, що вона отримала"? Git приносить усе з вилученням.
Олексій

@Alexey з посібника з git: git-scm.com/docs/git-fetch : Імена
PJ_Finnegan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.