2012-02-11 5 views
150

git pull --help говорит:Что означает FETCH_HEAD в Git?

В режиме по умолчанию, мерзавец тянуть стенография для мерзавца выборки с последующим мерзавца слияния FETCH_HEAD.

Что это такое FETCH_HEAD, и что фактически слилось во время git pull?

+2

Примечание: поскольку git 1.8.4 (август 2013 г.), 'git fetch origin master' фактически обновит' origin/master', а не только 'FETCH_HEAD'. См. Http://stackoverflow.com/a/20967347/6309 – VonC

+0

Подробнее о 'git merge FETCH_HEAD' (начиная с Git 2.5, Q2 2015) см. Http://stackoverflow.com/a/30425991/6309 – VonC

ответ

150

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 внутри вместо того, чтобы ссылаться на то, что сингл исх был неправдоподобным, вместо того, чтобы назвать вещи.

+1

Pull может выполнять rebase вместо слияния, если вы настроите его таким образом. –

+0

@AdamDymitruk: Конечно. Я описал поведение по умолчанию, полагая, что если кто-то его изменит, они узнают, что они его модифицировали. (Для полноты поведение идентично, заменяя 'merge FETCH_HEAD' на' rebase FETCH_HEAD'). – Cascabel

+5

@Jefromi: извините, я думаю, что вы ошибаетесь: насколько я понимаю, 'git fetch' обновляет (объединяет) все данные объекта из удаленного хранилища, а не только ** ** ** бранч. Поэтому я не понимаю из вашего ответа, как git решает до конца какой ветви точки FETCH_HEAD. Я также не могу найти 'FETCH_HEAD' в документации git (определение, а не примеры). Существование 'FETCH_HEAD' больше похоже на обходное решение, чтобы заставить' git pull' работать _somehow_. – Alexey

1

git pull - это комбинация извлечения, за которой следует слияние. Когда git fetch происходит, он замечает головную фиксацию того, что она выбрала в FETCH_HEAD (просто файл с этим именем в .git). Затем эти коммиты объединяются в ваш рабочий каталог.

+3

@manjolds, что вы подразумеваете под «_head commit_ из того, что он выбрал»? Git извлекает все с помощью fetch. – Alexey

+0

@Alexey от git manual: https://git-scm.com/docs/git-fetch: * Имена ссылок, которые выберутся вместе с именами объектов, на которые они указывают, записываются в .git/FETCH_HEAD * –

10

FETCH_HEAD является ссылкой на конец последней выборки, независимо от того, была ли эта выборка инициирована непосредственно с помощью команды fetch или как часть pull. Текущее значение 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 
4

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

git fetch gitserver release_1 

gitserver это имя моей машины, которая хранит GIT репозитории. release_1 - это тег для версии программного обеспечения. К моему удивлению, release_1 нигде не было на моей локальной машине. Я должен был набрать

git tag release_1 FETCH_HEAD 

завершить копию меченой цепи фиксации (release_1) из удаленного хранилища в локальном.Fetch обнаружил удаленный тег, скопировал фиксацию на мой локальный компьютер, не создал локальный тег, но установил FETCH_HEAD на значение commit, чтобы я мог его найти и использовать. Затем я использовал FETCH_HEAD для создания локального тега, который соответствовал тегу на пульте дистанционного управления. Это практическая иллюстрация того, что такое FETCH_HEAD и как его можно использовать, и может быть полезно кому-то еще интересно, почему git fetch не делает то, что вы наивно ожидаете.

На мой взгляд, лучше всего избегать для этой цели, и лучший способ добиться того, что я пытаюсь сделать, это

git fetch gitserver release_1:release_1 

т.е. принести release_1 и называть его release_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, чтобы избавиться от копии с сервера, как только исправление было выбрано на вашу ветку. (Я предполагаю, что есть хорошая чистая тегированная фиксация, содержащая все исправления ошибок на сервере!)

+0

Интересная обратная связь. +1 – VonC

+0

Спасибо. Я редактировал свое оригинальное сообщение, написанное, когда я впервые обнаружил FETCH_HEAD пару лет назад, поскольку он, похоже, поощрял копирование тега с использованием FETCH_HEAD, а не синтаксис source: dest для refspecs. Надеюсь, теперь я дал лучший пример того, как можно использовать FETCH_HEAD. – user3070485

3

Как указано в Jonathan's answer, 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 по существу соответствует удаленной версии ветви, которая в настоящее время проверена.

Смежные вопросы