很难理解git-fetch
我很难理解git-fetch的细微差别。 我明白,做一个fetch ,获取远程参考本地跟踪分支。
我有几个问题,但:
-
本地跟踪分支是否可能不存在? 如果是的话,它会自动创build?
-
如果我做一个
fetch并指定一个非跟踪分支作为目的地会发生什么? -
git-fetch的手册页指定:
git-fetch <options> <repository> <refspec>
我将如何使用refspec从远程主站获取内容到远程跟踪分支? 我相信这可能是可能的,如果我现在的头是主人,我跑
git fetch origin master
但是,我可以使用<+?src:dest> refspec来实现相同的function吗? 我想这会帮助我更好地理解这些概念。
还有一个问题:
我的.git / config文件具有以下用于抓取的行(仅显示相关的行):
fetch = +refs/heads/*:refs/remotes/origin/*
有人可以解释一下这一行究竟是什么意思?
首先,没有这样的本地跟踪分支的概念,只有远程跟踪分支。 所以origin / master是原始回购中master的远程跟踪分支。
通常你做git fetch $ remote ,它会更新所有的远程跟踪分支,并在需要时创build新分支。
但是,您也可以指定一个refspec,但不会触及您的远程跟踪分支,取而代之的是,它将获取您指定的分支并将其保存在FETCH_HEAD上,除非您指定了目的地。 一般来说,你不想搞砸这个。
最后,
fetch = +refs/heads/*:refs/remotes/origin/*
这意味着如果你这样做
git fetch origin
它实际上会做:
git fetch origin +refs/heads/*:refs/remotes/origin/*
这意味着远程头/ foobar将是本地遥控器/起源/ foobar ,加号表示即使他们不快速前进,他们也会更新。
也许你认为跟踪分支是与git pull和合并configuration相关的东西。
在他的回答中, felipec 回答了大多数有问题的问题 。
剩下的几个(大部分来自git fetch manpage;这在一些地方有点过时,不幸):
-
如果远程跟踪分支 (追踪某个远程存储库中某个分支的分支)不存在,则会创build它。
-
你读取的分支(
[+]<src>:<dst>)不需要驻留在remotes/<remote>/命名空间中。 例如,对于镜像库(git clone --mirror),git clone --mirror是1到1.在单独的远程布局之前(远程跟踪参考的远程remotes/<remote>/命名空间之前) 主分支被提取到称为原点的分支中。 即使是当前的标签也是以镜像的方式直接进入tags/名字空间的。 -
如果您正在进入分支(refspec
<src>:<dst>的右侧),Git将检查下载是否会导致快进,也就是说,如果<dst>当前状态是<src>的状态的祖先<src>在给定的远程仓库中,如果不是,并且不使用-f/--force选项来进行git-fetch,或者在refspec前面添加'+'(使用+<src>:<dst>refspec)会拒绝更新那个分支。 -
git fetch origin master相当于git fetch origin master:,而不是git fetch origin master:master; 它将主分支(远程原点 )的提取值存储在FETCH_HEAD中 ,而不是存储在主分支或远程跟踪remotes/origin/master分支中。 它可以跟着git merge FETCH_HEAD。 通常不是直接使用,而是作为一次性拉动而不设置远程跟踪分支的一部分:git pull <URL> <branch>。 -
+refs/heads/*:refs/remotes/origin/*作为remote.origin.fetchconfigurationvariables的值,意味着远程原点中的每个分支(ref inrefs/heads/namespace)被提取到分别命名的远程跟踪分支refs/remotes/origin/命名空间,例如原始 主分支(即refs/heads/masterref)将被提取到原始/主远程跟踪分支(即refs/remotes/origin/masterref)中。 “+”前缀表示即使在非快进的情况下,取指也会成功,这意味着当远程分支被重新设置或重绕(重置为过去的某个状态)或以其他方式修改时。
旁注:你可能会想要使用更高级别的git remote命令来pipe理远程存储库并获取更新。
请注意,Git的主要维护者现在(Git 2.1,2014年8月)添加了对git fetch解释:
(见Junio C gitster ( gitster ) 提交fcb14b0 :
configuration的远程跟踪分支
您经常通过定期和反复地从相同的远程存储库进行交互。 为了跟踪这样一个远程仓库的进度,
git fetch允许你configurationremote.<repository>.fetchconfigurationvariables。通常这样的variables可能看起来像这样:
[remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/*
这种configuration有两种使用方式:
当
git fetch在没有指定在命令行上获取哪些分支和/或标签的情况下运行时,例如git fetch origin或者git fetch,remote.<repository>.fetch值被用作remote.<repository>.fetch—它们指定要获取哪个ref和哪些地方参考更新 。
上面的例子将获取origin中存在的所有分支(即任何与值左侧相匹配的ref,refs/heads/*),并更新refs/remotes/origin/*相应的远程跟踪分支层次结构。当
git fetch在命令行上使用显式分支和/或标签来获取时,例如git fetch origin master,命令行给出的<refspec>决定了要获取什么(例如master,对于master:是一个短手,而这又意味着“获取'master''分支,但是我没有明确地说明用它从命令行更新的什么远程跟踪分支”),而示例命令将仅获取'master“分支。
remote.<repository>.fetch值确定哪个远程跟踪分支(如果有的话)被更新。
当以这种方式使用时,remote.<repository>.fetch值在决定获取的内容时没有任何作用(即,当命令行列表参考时,这些值不被用作refspecs)。 它们仅用于通过充当映射来确定被提取的ref的存储位置。
还要注意的是,在Git 2.5+(Q2 2015)中, git merge FETCH_HEAD可以合并多个git fetch 。
见Junio C gitster ( gitster ) ,2015年3月26日的提交d45366e 。
(由Junio C gitster合并- gitster – in commit bcd1ecd ,2015年5月19日)
“
git merge FETCH_HEAD”得知前面的“git fetch”可以创build一个Octopus合并,即logging多个没有标记为“不合并”的分支。
这允许我们在执行“git pull”脚本时失去一个老式的调用“git merge <msg> HEAD $commits...”; 旧式的语法现在可以被弃用。
git merge doc现在提到:
当
FETCH_HEAD(并且没有其他提交)时, 通过先前的git fetch调用进行合并logging在.git/FETCH_HEAD文件中的分支将合并到当前分支 。
Git 2.13(2017年第二季度)正式退休了旧的git merge语法。
参见Junio C gitster ( gitster )的 提交b439165 (2015年3月26日) 。
(由Junio C gitster合并- gitster – in commit 1fdbfc4 ,2017年3月30日)
merge:git merge <message> HEAD <commit>'语法停止支持自2007年10月以来已弃用的“
git merge <message> HEAD <commit>”语法,并自v2.5.0以来发出弃用警告消息。
这意味着老式的“ 'git merge <msg> HEAD <commit>' is deprecated.的警告信息'git merge <msg> HEAD <commit>' is deprecated. 。