Что означает FETCH_HEAD в Git?
git pull --help
говорит:
В режиме по умолчанию git pull является сокращением для git fetch, за которым следует git merge FETCH_HEAD.
Что это FETCH_HEAD
и что на самом деле сливается во время git pull
?
8 ответов
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
вместо того, чтобы ссылаться на какую-либо одну ссылку, вместо того, чтобы называть вещи.
FETCH_HEAD является ссылкой на подсказку последней выборки, независимо от того, была ли эта выборка инициирована непосредственно с помощью команды выборки или как часть извлечения. Текущее значение 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_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 по существу соответствует удаленной версии ветви, которая в настоящее время извлечена.
Я только что обнаружил и использовал 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 и вызвать его 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 для удаления копии с сервера после того, как исправление было выбрано в текущей ветке. (Я предполагаю, что на сервере есть хороший чистый тэг с фиксацией, содержащий все исправления ошибок!)
FETCH_HEAD
- кратковременная ссылка, чтобы отслеживать, что только что было извлечено из удаленного репозитория.
На самом деле... не всегда учитывая, что с Git 2.29 (4 квартал 2020 г.) " git fetch
"(человек) узнал--no-write-fetch-head
возможность избежать написания FETCH_HEAD
файл.
См. Commit 887952b (18 августа 2020 г.), автор Junio C Hamano (gitster
).
(Слияние Junio C Hamano -gitster
- в коммите b556050, 24 августа 2020 г.)
fetch
: опционально разрешить отключениеFETCH_HEAD
ОбновитьПодписано: Деррик Столи
Если вы запускаете выборку, но записываете результат в ветвях удаленного отслеживания, и либо если вы ничего не делаете с полученными ссылками (например, вы просто зеркалируете), либо если вы всегда работаете из ссылок удаленного отслеживания (например, вы извлекаете, а затем объединяете
origin/branchname
отдельно), вы можете обойтись безFETCH_HEAD
совсем.Учить "
git fetch
"(человек) параметр командной строки"--[no-]write-fetch-head
".
- По умолчанию нужно писать
FETCH_HEAD,
и этот параметр в первую очередь предназначен для использования с "--no-
"префикс, чтобы переопределить это значение по умолчанию, потому что нет соответствияfetch.writeFetchHEAD
переменная конфигурации, чтобы отключить значение по умолчанию (в этом случае может потребоваться положительная форма, чтобы победить его).Обратите внимание, что в разделе "
--dry-run
" Режим,FETCH_HEAD
никогда не пишется; в противном случае вы увидите список объектов в файле, которых у вас на самом деле нет.Проходящий
--write-fetch-head
не заставляет[
git fetch](https://github.com/git/git/blob/887952b8c680626f4721cb5fa57704478801aca4/Documentation/git-fetch.txt)<sup>([man](https://git-scm.com/docs/git-fetch))</sup>
записать файл.
fetch-options
теперь включает в свою справочную страницу:
--[no-]write-fetch-head
Напишите список удаленных ссылок, полученных в
FETCH_HEAD
файл прямо под$GIT_DIR
.
Это значение по умолчанию.Проходящий
--no-write-fetch-head
из командной строки указывает Git не записывать файл.
Под--dry-run
вариант, файл никогда не записывается.
Также обратите внимание на Git 2.29 (4 квартал 2020 г.), FETCH_HEAD
теперь всегда считывается из файловой системы независимо от используемого бэкэнда ref, так как его формат намного богаче, чем у обычных ссылок, и записывается непосредственно " git fetch
"(мужчина) простым файлом..
См. Фиксацию e811530, фиксацию 5085aef, фиксацию 4877c6c, фиксацию e39620f (19 августа 2020 г.) от Han-Wen Nienhuys (hanwen
).
(Слияние Junio C Hamano -gitster
- в коммите 98df75b, 27 августа 2020 г.)
refs
: читатьFETCH_HEAD
а такжеMERGE_HEAD
в целомПодписано: Хан-Вен Ниенхуйс
В
FETCH_HEAD
а такжеMERGE_HEAD
ссылки должны храниться в файле, независимо от типа бэкэнда ref. Это потому, что они могут содержать больше, чем один реф.Чтобы разместить их для альтернативных бэкэндов ссылок, прочтите их из файла в общем случае в
refs_read_raw_ref()
.
В Git 2.29 (четвертый квартал 2020 г.) обновления для получения кода по требованию в лениво клонированных репозиториях.
См. Commit db3c293 (2 сентября 2020 г.) и commit 9dfa8db, commit 7ca3c0a, commit 5c3b801, commit abcb7ee, commit e5b9421, commit 2b713c2, commit cbe566a (17 августа 2020 г.) Джонатан Тан (jhowtan
).
(Слияние Junio C Hamano -gitster
- в коммите b4100f3, 03 сен 2020)
fetch
: нетFETCH_HEAD
отображать, если --no-write-fetch-headПодписано: Джонатан Тан
887952b8c6 ("
fetch
: опционально разрешить отключениеFETCH_HEAD
update", 2020-08-18, Git v2.29.0 - слияние, указанное в пакете № 10), добавлена возможность отключения записи вFETCH_HEAD
во время выборки, но не подавил "<source> -> FETCH_HEAD"
сообщение при использовании этой способности.В данном случае это сообщение вводит в заблуждение, потому что
FETCH_HEAD
не написано.Также потому, что "
fetch
"используется для отложенной выборки недостающих объектов в частичном клоне, это значительно загромождает вывод в этом случае, поскольку извлекаемых объектов потенциально много.Поэтому подавите это сообщение, когда
--no-write-fetch-head
пройден (но не когда--dry-run
установлено).
git pull - это комбинация выборки с последующим слиянием. Когда происходит git fetch, он записывает главный коммит того, что он выбрал в FETCH_HEAD (просто файл с таким именем в.git), и эти коммиты затем объединяются в ваш рабочий каталог.
Я просто пытался вытащить ветку (исправление), которую я создал путем внесения изменений непосредственно из GitHub. Ветка появилась только на GH. Когда я попытался выполнить ag pull, ветка не появилась.
Я смог проверить ветку, используя:
git fetch origin pull/2/head
git checkout -b <desired-branch-name> FETCH_HEAD
Позвольте мне внести свой вклад в это, если это возможно.
На изображении я попросил УДАЛИТЬ, есть ли какие-то изменения в ФИЛИАЛЕ, над которым я работаю. FETCH сказал мне * ветка back_end -> FETCH_HEAD
ТОГДА я попросил PULL, пытаясь перенести все НОВОЕ на REMOTE (GITHUB) в свою локальную ветку (у нее такое же имя back_end)
GIT сказал мне --->> FETCH_HEAD, что означает, что все уже было обновлено, и было что обновить из REMOTE BRANCH, та же информация, которую мне сообщила инструкция FETCH ранее.