262

git pull --help说:

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

这是FETCH_HEAD什么以及在 期间实际合并了git pull什么?

4

7 回答 7

250

FETCH_HEAD是一个短暂的 ref,用于跟踪刚刚从远程存储库中获取的内容。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,而不是需要命名。

于 2012-02-11T03:11:37.767 回答
23

FETCH_HEAD 是对最后一次提取的提示的引用,无论该提取是使用 fetch 命令直接启动还是作为拉取的一部分。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
于 2012-12-10T11:37:49.897 回答
18

正如乔纳森的回答中提到的, 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 本质上对应于当前签出的分支的远程版本。

于 2017-08-07T09:36:49.380 回答
9

我刚刚发现并使用了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 的垃圾收集处理来自服务器的副本。(我假设有一个漂亮的干净标记提交,其中包含服务器上的整个错误修复!)

于 2014-09-08T09:30:01.933 回答
3

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

于 2012-02-11T02:45:03.500 回答
3

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

实际上,......并不总是考虑到这一点,在 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 但将结果记录在远程跟踪分支中,或者您对获取的 refs 不做任何事情(例如,您只是镜像),或者您总是从远程跟踪 refs 工作(例如,您获取然后origin/branchname单独合并),你可以完全没有FETCH_HEAD

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

  • 默认值为 writeFETCH_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 年第四季度),FETCH_HEAD现在总是从文件系统中读取,而不管使用的 ref 后端如何,因为它的格式比普通 refs 丰富得多,并且直接由“ git fetchman作为纯文件..

请参阅Han-Wen Nienhuys ( ) 的commit e811530commit 5085aefcommit 4877c6ccommit e39620f(2020 年 8 月 19 日(由Junio C Hamano 合并——提交 98df75b中,2020 年 8 月 27 日)hanwen
gitster

refs:阅读FETCH_HEADMERGE_HEAD一般

签字人:Han-Wen Nienhuys

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

要将它们容纳为备用 ref 后端,请从refs_read_raw_ref().


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

请参阅提交 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 年 8 月 18 日,Git v2.29.0 -批次 #10中列出的合并)引入了在获取期间禁用写入的能力,但没有抑制“当此能力为用过的。FETCH_HEAD<source> -> FETCH_HEAD"

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

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

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

于 2020-08-31T16:06:32.713 回答
0

我只是想拉下一个(补丁)分支,它是通过直接从 GitHub 进行更改而创建的。该分支仅出现在 GH 上。当我尝试做 ag pull 时,分支没有出现。

我能够使用以下方法签出分支:

git fetch origin pull/2/head
git checkout -b <desired-branch-name> FETCH_HEAD
于 2022-03-01T19:23:54.720 回答