我很难理解git-fetch的细微差别。我知道做fetch
,将远程引用提取到本地跟踪分支。
我有几个问题:
本地跟踪分支是否可能不存在?如果是,那么它会自动创建吗?
如果我执行fetch
并指定非追踪分支作为目的地会怎样?
git-fetch的手册页指定:
git-fetch <options> <repository> <refspec>
如何使用refspec将远程主服务器中的内容提取到其远程跟踪分支?我相信如果我现在的HEAD是主人并且我跑了
,这可能是可能的 git fetch origin master
但是,我可以使用<+?src:dest>
refspec来实现同样的目的吗?我认为这将有助于我更好地理解这些概念。
还有一个问题:
我的.git / config文件有以下行用于获取(仅显示相关行):
fetch = +refs/heads/*:refs/remotes/origin/*
有人可以解释这条线的确切含义吗?
答案 0 :(得分:59)
首先,没有本地跟踪分支的概念,只有远程跟踪分支。因此 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/*
这意味着远程 head / foobar 将是本地遥控器/起源/ foobar ,加号意味着即使它们不快 - 它们也会更新 - 前进。
您认为跟踪分支可能与 git pull 和合并配置相关。
答案 1 :(得分:23)
felipec有answered most of issues in question in his answer。
剩下的一些(大多数来自git fetch联机帮助页;不幸的是,在某些地方有点过时了):
如果远程跟踪分支(跟踪某个远程存储库中某个分支的分支)不存在,则会创建它。
您获取的分支(<dst>
中的[+]<src>:<dst>
)不需要驻留在remotes/<remote>/
命名空间中。例如,对于镜像存储库(git clone --mirror
),refspec是1到1.在过去,在单独的远程跟踪布局之前(远程跟踪引用的remotes/<remote>/
命名空间之前)已获取主分支进入名为 origin 的分支。即使是当前标签也会以镜像方式直接提取到tags/
命名空间。
如果您正在进入分支(refspec <src>:<dst>
的右侧确实存在,Git会检查下载是否会导致快进,即<dst>
中的当前状态是否为给定远程存储库中<src>
中的状态祖先。如果不是,则不使用-f
/ --force
选项进行git-fetch,或使用'+'作为前缀refspec (使用+<src>:<dst>
refspec)fetch会拒绝更新该分支。
git fetch origin master
相当于git fetch origin master:
,而不是git fetch origin master:master
;它在 FETCH_HEAD 中存储 master 分支(远程 origin )的获取值,而不是 master 分支或远程 - 跟踪remotes/origin/master
分支。可以跟随git merge FETCH_HEAD
。通常不直接使用,但作为一次性拉动的一部分而不设置远程跟踪分支:git pull <URL> <branch>
。
+refs/heads/*:refs/remotes/origin/*
作为 remote.origin.fetch 配置变量的值意味着远程源中的每个分支(ref refs/heads/
命名空间)被提取到refs/remotes/origin/
命名空间中的分别命名的远程跟踪分支中,例如 origin 中的主分支(即refs/heads/master
ref)将被提取到 origin / master 远程跟踪分支(即{{1 })ref。 '+'前缀意味着即使在非快进的情况下fetch也会成功,这意味着当远程分支被重新引导或重绕(在过去重置为某个状态)或以其他方式修改时。
旁注: 您可能希望使用更高级别的git remote命令来管理远程存储库并获取更新。
答案 2 :(得分:4)
请注意,Git的主要维护者现在(Git 2.1,2014年8月)为git fetch
添加了这个解释:
(commit fcb14b0见Junio C Hamano (gitster
):
您经常通过定期重复从中获取相同的远程存储库。为了跟踪此类远程存储库的进度,
git fetch
允许您配置remote.<repository>.fetch
配置变量。通常这样的变量可能如下所示:
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
此配置以两种方式使用:
运行
git fetch
时未指定要在命令行上获取的分支和/或标记,例如git fetch origin
或git fetch
,remote.<repository>.fetch
值用作 refspecs ---它们指定要获取的引用数据以及要更新的本地引用。
上面的示例将获取origin
中存在的所有分支(即与值的左侧匹配的任何ref,refs/heads/*
)并更新{{1}中相应的远程跟踪分支等级。使用显式分支和/或标记运行
refs/remotes/origin/*
以在命令行上获取时,例如git fetch
,命令行中给出的git fetch origin master
确定要获取的内容(例如,<refspec>
在示例中,这是master
的简写,其中turn意味着“获取'master:
'分支但我没有明确说明要从命令行”更新它的远程跟踪分支“,并且示例命令将仅提取 'master
'分支。
master
值确定更新哪个远程跟踪分支(如果有) 以这种方式使用时,remote.<repository>.fetch
值对决定获取的内容没有任何影响(即,当命令行列出refspecs时,这些值不用作refspecs);它们仅用于决定 where 通过充当映射来存储被提取的引用。
答案 3 :(得分:2)
另请注意,使用Git 2.5+(2015年第2季度),git merge FETCH_HEAD
可以合并多个git fetch&#39> 。
2015年3月26日commit d45366e见Junio C Hamano (gitster
)
(由Junio C Hamano -- gitster
--合并于commit bcd1ecd,2015年5月19日)
&#34;
git merge FETCH_HEAD
&#34;得知前一个&#34;git fetch
&#34;可能是创建一个八达通合并,即记录多个未标记为&#34的分支;不合并&#34;;
这使我们失去了旧式的调用&#34;git merge <msg> HEAD $commits...
&#34;在实施&#34;git pull
&#34;脚本;现在可以弃用旧样式语法。
git merge
doc现在提到:
当指定
FETCH_HEAD
(并且没有其他提交)时,先前调用.git/FETCH_HEAD
进行合并的git fetch
文件中记录的分支将合并到当前分支强>
Git 2.13(2017年第二季度)正式退出git merge
的旧语法
请commit b439165见Junio C Hamano (gitster
)(2015年3月26日)
(Junio C Hamano -- gitster
--于2017年3月30日commit 1fdbfc4合并)
merge
:drop&#39;git merge <message> HEAD <commit>
&#39;语法停止支持&#34;
git merge <message> HEAD <commit>
&#34;语法有 自2007年10月以来已弃用,并从v2.5.0开始发出弃用警告消息。
这意味着警告信息旧式&#34; 'git merge <msg> HEAD <commit>' is deprecated.
&#34;不再是。