很难理解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/master
ref)将被提取到原始/主远程跟踪分支(即refs/remotes/origin/master
ref)中。 “+”前缀表示即使在非快进的情况下,取指也会成功,这意味着当远程分支被重新设置或重绕(重置为过去的某个状态)或以其他方式修改时。
旁注:你可能会想要使用更高级别的git remote命令来pipe理远程存储库并获取更新。
请注意,Git的主要维护者现在(Git 2.1,2014年8月)添加了对git fetch
解释:
(见Junio C gitster
( gitster
) 提交fcb14b0 :
configuration的远程跟踪分支
您经常通过定期和反复地从相同的远程存储库进行交互。 为了跟踪这样一个远程仓库的进度,
git fetch
允许你configurationremote.<repository>.fetch
configurationvariables。通常这样的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.
。