Git拉——帮助说:

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

FETCH_HEAD是什么? git拉取过程中合并了什么?


当前回答

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

实际上,…并不总是考虑到这一点,在Git 2.29 (Q4 2020)中,“Git fetch”(man)学会了—no-write-fetch-head选项,以避免写入FETCH_HEAD文件。

参见juno C Hamano (gitster)提交的887952b(2020年8月18日)。 (由Junio C Hamano—gitster—在commit b556050中合并,2020年8月24日)

fetch:可选允许禁用FETCH_HEAD更新 署名:Derrick Stolee

If you run fetch but record the result in remote-tracking branches, and either if you do nothing with the fetched refs (e.g. you are merely mirroring) or if you always work from the remote-tracking refs (e.g. you fetch and then merge origin/branchname separately), you can get away with having no FETCH_HEAD at all. Teach "git fetch"(man) a command line option "--[no-]write-fetch-head". The default is to write FETCH_HEAD, and the option is primarily meant to be used with the "--no-" prefix to override this default, because there is no matching fetch.writeFetchHEAD configuration variable to flip the default to off (in which case, the positive form may become necessary to defeat it). Note that under "--dry-run" mode, FETCH_HEAD is never written; otherwise you'd see list of objects in the file that you do not actually have. Passing --write-fetch-head does not force [git fetch](https://github.com/git/git/blob/887952b8c680626f4721cb5fa57704478801aca4/Documentation/git-fetch.txt)<sup>([man](https://git-scm.com/docs/git-fetch))</sup> to write the file.

Fetch-options现在包含在它的手册页中:

——不——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)作为一个普通文件写入。

参见hanwen Nienhuys (hanwen)的commit e811530, commit 5085aef, commit 4877c6c, commit e39620f (19 Aug 2020)。 (由Junio C Hamano—gitster—在commit 98df75b中合并,2020年8月27日)

参考:读取FETCH_HEAD和MERGE_HEAD一般 签署人:Han-Wen Nienhuys

FETCH_HEAD和MERGE_HEAD引用必须存储在文件中,无论引用后端是什么类型。这是因为它们可以容纳不止一个裁判。 为了将它们用于备用的ref后端,一般从refs_read_raw_ref()中的文件中读取它们。


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

参见Jonathan Tan (jhowtan)的commit db3c293 (02 Sep 2020), and commit 9dfa8db, commit 7ca3c0a, commit 5c3b801, commit abcb7ee, commit e5b9421, commit 2b713c2, commit cbe566a (2020 Aug 17)。 (由Junio C Hamano - gitster - in commit b4100f3, 03 Sep 2020)

fetch:不显示FETCH_HEAD如果——no-write-fetch-head 署名:乔纳森·谭

887952b8c6 ("fetch: optionally allow disabling FETCH_HEAD update", 2020-08-18, Git v2.29.0 -- merge listed in batch #10) introduced the ability to disable writing to FETCH_HEAD during fetch, but did not suppress the "<source> -> FETCH_HEAD" message when this ability is used. This message is misleading in this case, because FETCH_HEAD is not written. Also, because "fetch" is used to lazy-fetch missing objects in a partial clone, this significantly clutters up the output in that case since the objects to be fetched are potentially numerous. Therefore, suppress this message when --no-write-fetch-head is passed (but not when --dry-run is set).

其他回答

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

git fetch gitserver release_1

Gitserver是存储git存储库的机器的名称。 Release_1是软件版本的标记。令我惊讶的是,在我的本地机器上找不到release_1。我必须打字

 git tag release_1 FETCH_HEAD 

to complete the copy of the tagged chain of commits (release_1) from the remote repository to the local one. Fetch had found the remote tag, copied the commit to my local machine, had not created a local tag, but had set FETCH_HEAD to the value of the commit, so that I could find and use it. I then used FETCH_HEAD to create a local tag which matched the tag on the remote. That is a practical illustration of what FETCH_HEAD is and how it can be used, and might be useful to someone else wondering why git fetch doesn't do what you would naively expect.

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

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的垃圾收集来处理服务器上的副本。(我假设在服务器上有一个干净的标记提交,包含了整个错误修复!)

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

正如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>

注意除了一个分支之外的所有分支都标记为not-for-merge。奇怪的是在取回之前检出的分支。总之:FETCH_HEAD本质上对应于当前签出的分支的远程版本。

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

在图像上,我已经向REMOTE询问了我正在工作的分支是否有一些变化。 FETCH已经告诉我*分支后台-> FETCH_HEAD 然后我要求拉,试图把所有新的远程(GITHUB)到我的本地分支(它有相同的名字back_end)

GIT告诉我——>> FETCH_HEAD,这意味着所有东西都已经更新了,有任何东西要从REMOTE BRANCH更新,与FETCH指令之前告诉我的信息相同。

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

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

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