很难理解git-fetch
我很难理解git-fetch的细微差别。 我知道执行<+?src:dest>
会将远程参考提取到本地跟踪分支中。
我有几个问题:
本地跟踪分支是否可能不存在? 如果是这样,它将自动创建吗?
如果我执行
<+?src:dest>
并将非跟踪分支指定为目的地,将会发生什么?git-fetch的手册页指定:
<+?src:dest>
我将如何使用refspec将内容从我的远程主服务器获取到其远程跟踪分支? 我相信,如果我当前的HEAD处于主人状态并且我跑步
<+?src:dest>
但是,我可以使用<+?src:dest>
refspec来实现同一目的吗? 我认为这将帮助我更好地理解概念。
还有一个问题:
我的.git / config文件具有以下用于提取的行(仅显示相关行):
fetch = +refs/heads/*:refs/remotes/origin/*
有人可以解释一下这行的确切含义吗?
首先,没有本地跟踪分支的概念,只有远程跟踪分支。 因此,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在回答中回答了大部分有问题的问题。
剩下的一些(大部分来自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命令来管理远程存储库并获取更新。
请注意,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 fetch
或git 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)。 它们仅用于通过充当映射来确定所提取的引用的存储位置。
另请注意,使用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.
”。