很难理解git-fetch

我很难理解git-fetch的细微差别。 我知道执行<+?src:dest>会将远程参考提取到本地跟踪分支中。

我有几个问题:

  1. 本地跟踪分支是否可能不存在? 如果是这样,它将自动创建吗?

  2. 如果我执行<+?src:dest>并将非跟踪分支指定为目的地,将会发生什么?

  3. git-fetch的手册页指定:

    <+?src:dest>

我将如何使用refspec将内容从我的远程主服务器获取到其远程跟踪分支? 我相信,如果我当前的HEAD处于主人状态并且我跑步

<+?src:dest>

但是,我可以使用<+?src:dest> refspec来实现同一目的吗? 我认为这将帮助我更好地理解概念。

还有一个问题:

我的.git / config文件具有以下用于提取的行(仅显示相关行):

fetch = +refs/heads/*:refs/remotes/origin/*

有人可以解释一下这行的确切含义吗?

Parag asked 2020-01-15T22:14:11Z
4个解决方案
60 votes

首先,没有本地跟踪分支的概念,只有远程跟踪分支。 因此,origin / master是Origin回购中master的远程跟踪分支。

通常,您执行git fetch $ remote来更新所有远程跟踪分支,并在需要时创建新的分支。

但是,您也可以指定一个refspec,但这不会影响您的远程跟踪分支,相反,它将获取您指定的分支并将其保存在FETCH_HEAD上,除非您指定了目的地。 通常,您不希望对此感到困惑。

最后,

fetch = +refs/heads/*:refs/remotes/origin/*

这意味着如果你这样做

git fetch origin

它实际上会做:

git fetch origin +refs/heads/*:refs/remotes/origin/*

这意味着远程heads / foobar将是本地remotes / origin / foobar,加号表示即使它们不是快进,它们也会被更新。

也许您认为跟踪分支与git pull和merge config有关。

FelipeC answered 2020-01-15T22:14:55Z
23 votes

felipec在回答中回答了大部分有问题的问题。

剩下的一些(大部分来自git fetch联机帮助页;不幸的是,这在某些地方有些过时了):

  • 如果不存在远程跟踪分支(在某个远程存储库中跟踪某个分支的分支),则将创建该分支。

  • 您提取到的分支(refs/heads/中的+refs/heads/*:refs/remotes/origin/*)不需要驻留在refs/remotes/origin/命名空间中。 例如,用于镜像存储库(refs/heads/master)的refspec是1到1。在过去,在单独的远程布局(在refs/remotes/origin/master远程跟踪ref的名称空间之前)之前,master分支被提取到称为origin的分支中。 甚至当前标签也以镜像方式直接获取到git pull <URL> <branch>命名空间中。

  • 如果您要获取的分支(refspec +refs/heads/*:refs/remotes/origin/*的右侧确实存在,Git将检查下载是否会导致快进,即,给定远程存储库中refs/heads/中的当前状态是否是2704299497739518518978中的祖先状态。 t,并且您不会在git-fetch中使用refs/heads/master/refs/remotes/origin/master选项,或者在refspec加上'+'前缀(使用git pull <URL> <branch> refspec)时,fetch会拒绝更新该分支。

  • +refs/heads/*:refs/remotes/origin/*等效于refs/heads/,而不是refs/remotes/origin/; 它将获取的主分支(远程源)的值存储在FETCH_HEAD中,而不存储在主分支或远程跟踪refs/heads/master分支中。 它后面可以接refs/remotes/origin/master。通常不直接使用,而是作为一次拉动的一部分,而未设置远程跟踪分支:git pull <URL> <branch>

  • +refs/heads/*:refs/remotes/origin/*作为remote.origin.fetch配置变量的值表示将远程来源中的每个分支(引用在refs/heads/名称空间中)分别提取到refs/remotes/origin/命名空间中分别命名的远程跟踪分支中。 将原始来源的主分支(即refs/heads/master参考)提取到原始/主远程跟踪分支(即refs/remotes/origin/master ref)中。 “ +”前缀表示即使在非快进情况下,提取也将成功,这意味着对远程分支进行重新设置,重新缠绕(过去重置为某些状态)或进行其他修改时。

旁注:您可能希望使用更高级别的git remote命令来管理远程存储库并获取更新。

Jakub Narębski answered 2020-01-15T22:15:50Z
4 votes

请注意,Git的主要维护者现在(2014年8月,Git 2.1)为git fetch添加了以下说明:
(参见Junio C Hamano(git fetch)的commit fcb14b0:

配置的远程分支

您经常通过定期重复地从同一个远程存储库中进行交互来与之交互。 为了跟踪此类远程存储库的进度,git fetch允许您配置remote.<repository>.fetch配置变量。

通常,这样的变量可能看起来像这样:

[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*

此配置有两种使用方式:

  • 在运行git fetch时未指定要在命令行上提取的分支和/或标记的位置,例如 git fetchgit fetch origin master<refspec>值用作refspecs ---它们指定要获取的ref和要更新的本地ref。
    上面的示例将获取master中存在的所有分支(即,与值master:的左侧匹配的任何引用),并更新master层次结构中的相应远程跟踪分支。

  • 当使用明确的分支和/或标记运行git fetch以在命令行上进行提取时,例如 git fetch origin master,在命令行上给出的<refspec>s确定要获取的内容(例如,本示例中的master,它是master:的简写形式,这又意味着“获取'master”分支,但我没有明确说明远程对象 -tracking分支以从命令行进行更新”),示例命令将仅获取“ master”分支。
    remote.<repository>.fetch值确定更新哪个远程跟踪分支(如果有)。
    以这种方式使用时,remote.<repository>.fetch的值在决定获取什么内容时没有任何作用(即,当命令行列出refspec时,这些值不用作refspec)。 它们仅用于通过充当映射来确定所提取的引用的存储位置。

VonC answered 2020-01-15T22:16:57Z
2 votes

另请注意,使用Git 2.5+(2015年第二季度),'git merge <msg> HEAD <commit>' is deprecated.可以合并多个git fetch。

参见Junio C Hamano('git merge <msg> HEAD <commit>' is deprecated.)的commit d45366e,2015年3月26日。
(由Junio C Hamano合并-'git merge <msg> HEAD <commit>' is deprecated.-在commit bcd1ecd中,2015年5月19日)

'git merge <msg> HEAD <commit>' is deprecated.”获悉先前的“ git merge <message> HEAD <commit>”可以创建八达通合并,即记录未标记为“不可合并”的多个分支;
这使我们在执行“ git pull”脚本时丢失了旧式调用“ git merge <msg> HEAD $commits...”; 现在可以弃用旧样式的语法。

'git merge <msg> HEAD <commit>' is deprecated.文档现在提到:

当指定'git merge <msg> HEAD <commit>' is deprecated.(且没有其他提交)时,先前通过git merge <message> HEAD <commit>进行的合并调用在'git merge <msg> HEAD <commit>' is deprecated.文件中记录的分支将合并到当前分支。


Git 2.13(2017年第二季度)正式淘汰了'git merge <msg> HEAD <commit>' is deprecated.的旧语法。
参见Junio C Hamano('git merge <msg> HEAD <commit>' is deprecated.)的commit b439165(2015年3月26日)。
(由Junio C Hamano合并-'git merge <msg> HEAD <commit>' is deprecated.-在commit 1fdbfc4中,2017年3月30日)

'git merge <msg> HEAD <commit>' is deprecated.:删除'git merge <message> HEAD <commit>'语法

停止支持具有以下内容的“ 'git merge <msg> HEAD <commit>' is deprecated.”语法   自2007年10月起已弃用,并且自v2.5.0起发出弃用警告消息。

这意味着警告消息不再是老式的“ 'git merge <msg> HEAD <commit>' is deprecated.”。

VonC answered 2020-01-15T22:18:11Z
translate from https://stackoverflow.com:/questions/1070496/having-a-hard-time-understanding-git-fetch