git pull --help
говорит:
В режиме по умолчанию git pull является сокращением для git fetch, за которым следует git merge FETCH_HEAD.
Что это за FETCH_HEAD
, и что фактически слилось во время git pull
?
git pull --help
говорит:
В режиме по умолчанию git pull является сокращением для git fetch, за которым следует git merge FETCH_HEAD.
Что это за FETCH_HEAD
, и что фактически слилось во время git pull
?
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
вместо этого вместо ссылки на какой-либо один ref был выбран необходимости называть вещи.
FETCH_HEAD является ссылкой на конец последней выборки, независимо от того, была ли эта выборка инициирована непосредственно с помощью команды извлечения или как часть 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
Я только что открыл и использовал FETCH_HEAD. Мне нужна локальная копия некоторого программного обеспечения с сервера, и я сделал
git fetch gitserver release_1
gitserver - это имя моей машины, в которой хранятся репозитории git. release_1 - это тег для версии программного обеспечения. К моему удивлению, release_1 нигде не было найдено на моей локальной машине. Мне пришлось набрать
git tag release_1 FETCH_HEAD
чтобы завершить копирование цепочки цепочек с тегами (release_1) из удаленного репозитория на локальный. Это практическая иллюстрация того, что такое FETCH_HEAD и как его можно использовать, и может быть полезным для кого-то еще, задающегося вопросом, почему git fetch не делает то, что вы наивно ожидаете.
Как упоминалось в Jonathan 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 в основном соответствует удаленной версии ветки, которая в настоящее время проверена.
git pull - это комбинация извлечения, за которой следует слияние. Когда git fetch происходит, он замечает головную фиксацию того, что она извлекла в FETCH_HEAD (просто файл с этим именем в .git) И эти коммиты затем объединяются в ваш рабочий каталог.