【问题标题】:What does FETCH_HEAD in Git mean?Git 中的 FETCH_HEAD 是什么意思?
【发布时间】:2012-03-03 11:41:23
【问题描述】:

git pull --help 说:

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

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

【问题讨论】:

标签: git git-pull git-fetch


【解决方案1】:

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

实际上,……考虑到这一点,并不是总是,“git fetch(man) 学习了 --no-write-fetch-head 选项避免写入FETCH_HEAD 文件。

参见 Junio C Hamano (gitster)commit 887952b(2020 年 8 月 18 日)。
(由 Junio C Hamano -- gitster -- 合并到 commit b556050,2020 年 8 月 24 日)

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

签字人:Derrick Stolee

如果您运行 fetch 但将结果记录在远程跟踪分支中,或者如果您对获取的 refs 不做任何事情(例如,您只是镜像)或者您总是从远程跟踪 refs 工作(例如,您获取和然后分别合并origin/branchname),你可以完全没有FETCH_HEAD

教“git fetch(man)一个命令行选项“--[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 现在包含在其man page 中:

--[no-]write-fetch-head

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

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


还请考虑,仍然使用 Git 2.29(2020 年第四季度),现在始终从文件系统中读取 FETCH_HEAD,而不管使用的 ref 后端如何,因为它的格式比普通 refs 丰富得多,并且直接由“ git fetch"(man) 作为普通文件..

参见Han-Wen Nienhuys (hanwen)commit e811530commit 5085aefcommit 4877c6ccommit e39620f(2020 年 8 月 19 日)。
(由 Junio C Hamano -- gitster -- 合并到 commit 98df75b,2020 年 8 月 27 日)

refs:一般阅读FETCH_HEADMERGE_HEAD

签字人:Han-Wen Nienhuys

FETCH_HEADMERGE_HEAD 引用必须存储在一个文件中,无论引用后端的类型如何。 这是因为它们可以容纳的不仅仅是单个 ref

要将它们用于备用 ref 后端,请从一般位于 refs_read_raw_ref() 的文件中读取它们。


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

请参阅commit db3c293(2020 年 9 月 2 日)和 commit 9dfa8dbcommit 7ca3c0acommit 5c3b801commit abcb7eecommit e5b9421commit 2b713c2commit cbe566a(2020 年 8 月 17 日)@9876 .
(由 Junio C Hamano -- gitster -- 合并于 commit b4100f3,2020 年 9 月 3 日)

fetch: no FETCH_HEAD 显示 if --no-write-fetch-head

签字人:Jonathan Tan

887952b8c6(“fetch:可选地允许禁用FETCH_HEAD更新”,2020-08-18,Git v2.29.0 -- mergebatch #10 中列出)引入了禁用写入@的功能获取期间为 987654398@,但在使用此功能时没有抑制“<source> -> FETCH_HEAD" 消息。

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

此外,由于“fetch”用于延迟获取部分克隆中丢失的对象,因此在这种情况下,由于要获取的对象可能很多,因此会显着混淆输出。

因此,在传递 --no-write-fetch-head 时禁止显示此消息(但在设置 --dry-run 时不显示)。

【讨论】:

    【解决方案2】:

    我刚刚发现并使用了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
    

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

    【讨论】:

    • 有趣的反馈。 +1
    • 谢谢。我编辑了我的原始帖子,该帖子是几年前我第一次发现 FETCH_HEAD 时写的,因为它似乎鼓励使用 FETCH_HEAD 而不是 refspecs 的 source:dest 语法来复制标签。希望我现在给出了一个更好的例子来说明如何使用 FETCH_HEAD。
    【解决方案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 本质上对应于当前签出的分支的远程版本。

    【讨论】:

      【解决方案4】:

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

      所以如果我发出:

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

      FETCH_HEAD 可能包含

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

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

      git merge FETCH_HEAD
      

      【讨论】:

      • 加我的 5 美分。让我感到困惑的是,我的 FETCH_HEAD 落后于最新的提交,即使做了一个返回“没有更改”的新提取(在 Eclipse 中)。我认为原因是,自上次获取以来的所有更改都来自我自己,并由我推送到服务器。所以随后的 fetch 没有任何事情可做,甚至没有更新 FETCH_HEAD。我不确定这是否是 GIT 或 Eclipse Git 实现的缺点。
      【解决方案5】:

      FETCH_HEAD 是一个短暂的引用,用于跟踪刚刚从远程存储库获取的内容。 git pull首先调用git fetch,正常情况下从远程获取一个分支; FETCH_HEAD 指向这个分支的尖端(它存储提交的 SHA1,就像分支一样)。 git pull 然后调用git merge,将FETCH_HEAD 合并到当前分支中。

      结果正是您所期望的:相应远程分支尖端的提交被合并到当前分支尖端的提交中。

      这有点像在不带参数的情况下执行git fetch(或git remote update),更新所有远程分支,然后运行git merge origin/&lt;branch&gt;,但在内部使用FETCH_HEAD 来引用获取的任何单个引用,而不是需要命名的东西。

      【讨论】:

      • @Jefromi:对不起,我认为你错了:据我了解,git fetch 更新(合并)来自远程存储的所有对象数据,而不仅仅是 a早午餐。所以我从你的回答中不明白git如何决定指向哪个分支的尖端FETCH_HEAD。我在 git 文档中也找不到FETCH_HEAD(定义,而不是示例)。 FETCH_HEAD 的存在在我看来更像是一种解决方法,让 git pull以某种方式工作。
      • Alexey:FETCH_HEAD对应本地仓库配置中branch.&lt;BRANCH&gt;.merge指定的远程分支的tip。因此,虽然fetch 确实从远程存储中获取所有对象数据,但FETCH_HEAD 用于指示本地分支跟踪的远程分支已前进到何处。所以如果你在本地的master 分支上运行git fetch,并且branch.master.merge 指向refs/heads/master,那么FETCH_HEAD 将在获取操作后立即与origin/master 具有相同的值。
      • @alexy FETCH_HEAD 在其手册页中 git fetch 描述的第二段中进行了描述。我的回答是正确的。并且不带参数的 git fetch 确实会更新默认远程的所有远程分支......但这绝对与合并不同。
      • 如果您通过git fetch -a 获取所有远程分支,FETCH_HEAD 是什么?
      • 正如@Alexey 建议和@CarstenFührmann 进一步澄清的那样,不,FETCH_HEAD 不仅仅包含一个分支。它包含所有上次获取的远程分支信息。
      【解决方案6】:

      git pull 是 fetch 和 merge 的组合。当 git fetch 发生时,它会记录它在 FETCH_HEAD 中获取的内容的头部提交(只是 .git 中具有该名称的文件),然后这些提交将合并到您的工作目录中。

      【讨论】:

      • @manjolds,您所说的“head commit 获取的内容”是什么意思? Git 使用 fetch 获取所有内容。
      • @Alexey from git manual: git-scm.com/docs/git-fetch: 获取的 refs 的名称,连同它们指向的对象名称,被写入 .git/FETCH_HEAD
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 2012-12-22
      • 1970-01-01
      • 2021-05-25
      相关资源
      最近更新 更多