Git 中的 FETCH_HEAD 是什么意思?

git pull --help表示:

在默认模式下,git pullgit fetch的简写,后跟 git merge FETCH_HEAD

什么是 FETCH_HEAD,什么是在 git pull期间实际合并的?

258645 次浏览

Git pull是一个fetch和merge的组合。当git获取发生时,它会注意到它在FETCH_HEAD中获取的内容的头提交(只是一个在.git中同名的文件),然后这些提交被合并到你的工作目录中。

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命令启动的,还是作为拉取的一部分。FETCH_HEAD的当前值存储在.git文件夹中的一个名为FETCH_HEAD的文件中。

所以如果我发出:

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

FETCH_HEAD可以包含

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

如果我将远程回购配置为远程跟踪分支,那么我可以使用跟踪分支的合并来跟踪我的fetch。如果我不这样做,我可以合并尖端的最后获取直接使用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已经找到了远程标记,将提交复制到我的本地机器,没有创建了一个本地标记,但已经将FETCH_HEAD设置为提交的值,以便我可以找到并使用它。然后,我使用FETCH_HEAD创建了一个与远程上的标记匹配的本地标记。这是一个关于FETCH_HEAD是什么以及如何使用它的实际说明,并且可能对其他想知道为什么git取回不做你天真期望的事情的人有用。

在我看来,为了达到这个目的,最好避免这样做,而实现我想要做的更好的方法是

git fetch gitserver 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

从你的Git服务器上使用bug修复号1234可能是一个很好的方法,并且一旦修复被选中到你当前的分支上,让Git的垃圾收集来处理服务器上的副本。(我假设在服务器上有一个干净的标记提交,包含了整个错误修复!)

正如在乔纳森的回答中提到的,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 2.29 (Q4 2020)中,“__abc4”(man)学习了--no-write-fetch-head选项以避免写入FETCH_HEAD文件。

参见提交887952 b (18 Aug 2020) by juno C Hamano (gitster)
(由Junio C Hamano—gitster in 提交b556050合并,24 Aug 2020)

fetch:可选地允许禁用FETCH_HEAD更新

署名:Derrick Stolee

如果你运行fetch但是在远程跟踪分支中记录结果,或者如果你对所获取的引用什么都不做(例如你只是镜像),或者如果你总是从远程跟踪引用中工作(例如你分别获取和合并origin/branchname),你可以根本没有FETCH_HEAD

教“git fetch"(man)”一个命令行选项。

  • 默认值是FETCH_HEAD,,该选项主要用于“__abc1”;前缀来覆盖这个默认值,因为没有匹配的fetch.writeFetchHEAD配置变量来将默认值翻转为关闭(在这种情况下,可能需要使用正形式来击败它)。

注意,在“;--dry-run"mode, 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

写入直接在$GIT_DIR下面的FETCH_HEAD文件中获取的远程引用列表。
这是默认值。

从命令行传递--no-write-fetch-head告诉 Git不写文件。
--dry-run选项下,文件永远不会被写入


还要考虑一下,仍然使用Git 2.29 (Q4 2020), FETCH_HEAD现在总是从文件系统中读取,而不管使用的ref后端是什么,因为它的格式比普通的ref丰富得多,并且直接由"git fetch"(man)作为一个普通文件写入。

参见提交e811530提交5085年时提交4877年c6c提交e39620f (19 Aug 2020) by 韩文·尼恩胡斯(hanwen)
(由Junio C Hamano—gitster in 提交98年df75b合并,27 Aug 2020)

refs:一般地读取FETCH_HEADMERGE_HEAD

签署人:Han-Wen Nienhuys

FETCH_HEADMERGE_HEAD引用必须存储在文件中,不管引用后端是什么类型。这是因为它们可以容纳不止一个裁判

为了使它们适用于备选的引用后端,一般从refs_read_raw_ref()中的文件中读取它们。


在Git 2.29 (Q4 2020)中,更新到惰性克隆存储库中的按需抓取代码。

参见谭恩美(jhowtan)提交db3c293 (02 Sep 2020)和提交9 dfa8db提交7 ca3c0a提交5 c3b801提交abcb7ee提交e5b9421提交2 b713c2提交cbe566a (17 Aug 2020)。
(由Junio C Hamano—gitster in 提交b4100f3合并,03 Sep 2020)

fetch:如果——no-write-fetch-head,不显示FETCH_HEAD

署名:乔纳森·谭

887952 b8c6(“fetch:可选地允许禁用FETCH_HEAD更新”,2020-08-18,Git v2.29.0——合并列在批# 10中)引入了在读取过程中禁止写入FETCH_HEAD的能力,但在使用此能力时并没有抑制“<source> -> FETCH_HEAD"”消息。

在这种情况下,此消息具有误导性,因为没有编写FETCH_HEAD

此外,因为"fetch"用于延迟获取部分克隆中缺失的对象,在这种情况下,这会使输出严重混乱,因为要获取的对象可能很多。

因此,当传递--no-write-fetch-head时(而不是设置--dry-run时),抑制此消息。

我只是试图下拉一个(补丁)分支,我从直接从GitHub进行更改创建。 该分支只出现在GH上。当我试着做一个g拉,分支没有显示

我能够使用以下命令签出分支:

git fetch origin pull/2/head
git checkout -b <desired-branch-name> FETCH_HEAD

如果可能的话,让我为之贡献力量。

  1. 在图像上,我已经向REMOTE询问我正在工作的BRANCH是否有一些变化。 FETCH已经告诉我* branch back_end ->FETCH_HEAD < / p >

  2. 然后我已经要求拉,试图把一切新的远程(GITHUB)到我的本地分支(它有相同的名称back_end)

GIT告诉我——>>FETCH_HEAD,意思是所有东西都已经更新了,还有东西要从REMOTE BRANCH更新,和FETCH指令之前告诉我的信息一样。

enter image description here