Git中的FETCH_HEAD是什么意思?

Mis*_*hko 194 git git-fetch

git pull --help 说:

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

这是什么FETCH_HEAD,以及实际合并期间git pull

Cas*_*bel 195

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内部使用而不是引用任何单个引用,而不是需要命名.

  • Alexey:`FETCH_HEAD`对应于本地存储库配置中`branch.<BRANCH> .merge`指定的远程分支的尖端.因此,虽然`fetch`确实从远程存储器获取所有对象数据,但是`FETCH_HEAD`用于指示本地分支跟踪的远程分支已经前进的位置.因此,如果你在本地`master`分支并运行`git fetch`,`branch.master.merge`指向`refs/heads/master`,那么`FETCH_HEAD`将具有与`origin/master相同的值`在获取操作后立即执行. (14认同)
  • @Jefromi:对不起,我认为你错了:据我所知,`git fetch`更新(合并)来自远程存储的所有对象数据,而不仅仅是**早午餐.所以我从你的回答中不明白git如何决定指向`FETCH_HEAD`的分支的尖端.我也在git文档中找不到`FETCH_HEAD`(定义,而不是例子).`FETCH_HEAD`的存在对我来说更像是一种解决方法,使`git pull`工作_somehow_. (8认同)
  • @alexy FETCH_HEAD在其手册页的git fetch描述的第二段中描述.我的回答是对的.并且没有参数的git fetch会更新默认远程的所有远程分支...但这绝对不同于合并. (4认同)
  • 如果你通过`git fetch -a`获取所有远程分支,那么`FETCH_HEAD`是什么? (4认同)
  • 如果您以这种方式配置,Pull 可能会执行变基而不是合并。 (2认同)
  • @stigi当前签出分支的远程跟踪分支的尖端指向git config.请在上面的评论中查看larsks的回答. (2认同)
  • 正如@Alexey所暗示的和@CarstenFührmann进一步阐明的那样,不,`FETCH_HEAD`不仅仅包含一个分支。它包含所有最近获取的远程分支信息。 (2认同)

Jon*_*ell 15

FETCH_HEAD是对最后一次提取的提示的引用,无论该提取是使用fetch命令直接启动还是作为pull的一部分启动.FETCH_HEAD的当前值存储在.git名为的文件夹中,您猜对了FETCH_HEAD.

所以,如果我发出:

git fetch https://github.com/ryanmaxwell/Fragaria
Run Code Online (Sandbox Code Playgroud)

FETCH_HEAD可能包含

3cfda7cfdcf9fb78b44d991f8470df56723658d3        https://github.com/ryanmaxwell/Fragaria
Run Code Online (Sandbox Code Playgroud)

如果我将远程仓库配置为远程跟踪分支,那么我可以通过合并跟踪分支来跟踪我的提取.如果我不这样做,我可以直接使用FETCH_HEAD合并最后一次获取的提示.

git merge FETCH_HEAD
Run Code Online (Sandbox Code Playgroud)

  • 添加我的 5 美分。让我困惑的是,我的 FETCH_HEAD 落后于最新的提交,即使执行一次返回“无更改”的新提取(在 Eclipse 中)。我认为原因是,自上次获取以来的所有更改均来自我自己,并由我推送到服务器。所以后续的 fetch 没有任何事可做,甚至没有更新 FETCH_HEAD。我不确定这是否是 GIT 或 Eclipse Git 实现的缺点。 (2认同)

Car*_*ann 9

正如Jonathan的回答中所提到,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>
Run Code Online (Sandbox Code Playgroud)

请注意除了一个分支以外的所有分支not-for-merge.奇怪的是在获取之前检出的分支.总结:FETCH_HEAD基本上对应于当前检出的分支的远程版本.


Iva*_*van 8

我刚刚发现并使用过FETCH_HEAD.我想从服务器获得一些软件的本地副本,我做了

git fetch gitserver release_1
Run Code Online (Sandbox Code Playgroud)

gitserver是存储git存储库的我的机器的名称. release_1是该软件版本的标签.令我惊讶的是,release_1在我的本地机器上无处可寻.我不得不打字

 git tag release_1 FETCH_HEAD 
Run Code Online (Sandbox Code Playgroud)

完成从远程存储库到本地存储的标记提交链(release_1)的副本.Fetch找到了远程标记,将提交复制到我的本地机器,没有创建本地标记,但已设置FETCH_HEAD为提交的值,以便我可以找到并使用它.然后我用来FETCH_HEAD创建一个与遥控器上的标签相匹配的本地标签.这是一个实际的例子,FETCH_HEAD说明它是什么以及如何使用,并且可能对其他人有用,想知道为什么git fetch不会做你想要的那样.

在我看来,最好避免出于这个目的而更好地实现我想要做的事情

git fetch gitserver release_1:release_1
Run Code Online (Sandbox Code Playgroud)

即获取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
Run Code Online (Sandbox Code Playgroud)

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


Von*_*onC 5

FETCH_HEAD是一个短暂的引用,用于跟踪刚刚从远程存储库中获取的内容。

实际上,......并不总是考虑到这一点,在 Git 2.29(2020 年第四季度)中,“ git fetchman学会了--no-write-fetch-head避免写入FETCH_HEAD文件的选项。

请参阅Junio C Hamano ( )的提交 887952b(2020 年 8 月 18 日)。(由Junio C Hamano 合并 -- --提交 b556050中,2020 年 8 月 24 日)gitster
gitster

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

签署人:Derrick Stolee

如果您运行 fetch 但将结果记录在远程跟踪分支中,并且您对获取的引用不执行任何操作(例如,您只是镜像),或者如果您始终从远程跟踪引用工作(例如,您分别获取然后origin/branchname合并),你可以FETCH_HEAD完全没有。

教“ git fetchman命令行选项“ --[no-]write-fetch-head”。

  • 默认值是 write 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(2020 年第 4 季度),FETCH_HEAD无论使用的引用后端如何,现在总是从文件系统读取,因为它的格式比普通引用丰富得多,并且直接由“ git fetchman作为普通文件..

请参阅Han-Wen Nienhuys ( )的提交 e811530提交 5085aef提交 4877c6c提交 e39620f(2020 年 8 月 19 日)。(由Junio C Hamano 合并 -- --提交 98df75b中,2020 年 8 月 27 日)hanwen
gitster

refs:阅读FETCH_HEADMERGE_HEAD一般

签署人:Han-Wen Nienhuys

无论 ref 后端的类型如何,FETCH_HEAD和refs都必须存储在文件中。这是因为它们可以容纳多个 refMERGE_HEAD

为了将它们容纳到备用引用后端,请从通常在refs_read_raw_ref().


使用 Git 2.29(2020 年第 4 季度),更新了延迟克隆存储库中的按需获取代码。

请参阅提交 db3c293(2020 年 9 月 2 日)、提交 9dfa8db提交 7ca3c0a提交 5c3b801提交 abcb7ee提交 e5b9421提交 2b713c2提交 cbe566a(2020 年 8 月 17 日),作者:Jonathan Tan ( jhowtan)
(由Junio C Hamano 合并 -- gitster--提交 b4100f3中,2020 年 9 月 3 日)

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

签署人: Jonathan Tan

887952b8c6(“ 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设置时)抑制此消息。


在 Git 2.41(2023 年第 2 季度)中,此选项已正确传播:

请参阅Eric Wong ( )提交的提交 15184ae(2023 年 3 月 8 日)。(由Junio C Hamano 合并 -- --提交947604d,2023 年 3 月 19 日)ele828
gitster

fetch: 传递--no-write-fetch-head给子进程

签署人:Eric Wong

用户似乎希望这个选项能够工作,无论它是从单个远程、多个远程获取还是递归到子模块中。