这是真的,git pull
真的只是git fetch
plus git merge
。但是有很多警告。
获取
当你运行时:
$ git fetch origin master
这表示”:
$ git fetch origin master:FETCH_HEAD
它告诉git fetch
你跑过origin
去问他们——github,在这种情况下,我将在这里使用“他们”和“他们”来指代origin
,所以“它”的意思是“你的获取”——他们对 branch 有什么master
。无论他们拥有什么,它都会带来,但它会将其置于当地的特殊名称之下FETCH_HEAD
。
如果您改为运行:
$ git fetch origin
这个“手段”是fetch
跑过origin
去问他们所有的树枝,把它们都当作“偏远的树枝”带过来。如果他们有分支“master”和“experiment”,它会将它们作为“远程分支”origin/master
和origin/experiment
.
git 合并
首先,git merge
始终合并到您当前的分支*
(在输出中标有 a 的分支git branch
)。1 换句话说,它知道要合并到哪里。不过,您需要告诉它从哪里合并。
如果你运行:
$ git merge
没有参数,它必须弄清楚你想要“合并”的提交 ID。它通过查找配置变量merge.defaultToUpstream
. 如果你得到:
fatal: No commit specified and merge.defaultToUpstream not set.
这意味着merge.defaultToUpstream
未设置,或设置为false
而不是true
。
如果你运行,它会告诉 git merge 要“合并”什么,所以它不需要这个特殊的配置变量。因此:git merge name-or-ID
$ git merge FETCH_HEAD
意思是“找到”指定的提交FETCH_HEAD
。或者,如果您运行:
$ git merge origin/master
这意味着“找到由”指定的提交origin/master
。
重要提示:如果您为 提供多个额外参数git merge
,它会执行“章鱼合并”(我不会在此答案中描述)。这意味着它git merge origin master
与git merge origin/master
. 斜杠有很大的不同,因为它将merge
命令从两个参数合并更改为一个参数合并。(我认为这是不幸的——和/或糟糕的设计——让git pull
你完全使用这些论点,但它们的含义与 .) 完全不同git merge
。)
把它们放在一起
那么,你想什么时候供应FETCH_HEAD
,git merge
什么时候供应origin/master
呢?好吧,回去重新阅读上面关于git fetch的部分。
该FETCH_HEAD
方法是旧的2方法,在这种方法中,您可以告知git fetch
要从中获取的位置和要从中获取的分支,并将git fetch
结果写入特殊名称下FETCH_HEAD
。您获取的分支无关紧要:git fetch origin inigo_montoya
, git fetch origin you_killed_my_father
, git fetch origin inconceivable
: 它们都过来并重命名FETCH_HEAD
,所以这就是您合并的内容。
该origin/master
方法是新的3方式:你跑步git fetch origin
,它只是把一切都带过来,你可以慢慢来,在闲暇时浏览“远程分支”。一旦您对它感到满意origin/master
并准备好将其合并,您就可以通过它的(清晰、简单和明显的)名称来合并它,而不是按FETCH_HEAD
.
git 拉
唉,git pull
。4脚本仍然使用 “pull
旧方式”。当您运行时git pull origin master
,或者甚至git pull
没有参数时,5它最终会运行git fetch origin master
,这使得git fetch
行为成为“旧方式”。然后它必须使用git merge FETCH_HEAD
,因为它只是运行git fetch
使得 fetch 没有更新origin/master
。6
1即使您处于“分离的 HEAD”模式,git merge
仍然会合并到您的“当前分支”,有点。只是最接近“当前分支”的东西现在是“分离的 HEAD”。
2或者也许是“传统的”。我希望它是“过时的”,这可能最终会发生,但现在它已经根深蒂固。
3远胜于上。:-)
4我不喜欢git pull
。这意味着一种便利,由于它坚持以“旧方式”做事,它最终变得不那么方便,更不用说它长期以来一直存在的一个罕见但严重的错误(在 git 1.8.4 中修复)。
5不带参数,git pull
从当前分支的配置中获取远程和分支的名称。例如,如果您在 branch 上,则master
git 会读取branch.master.remote
andbranch.master.merge
来获取origin
and master
。这些是使本地分支master
成为“跟踪分支”的相同值,跟踪远程分支origin/master
。这很好,除了git pull
强制git fetch
不更新origin/master
。所以git pull
更新你的 local master
,但留下 git 告诉你现在领先的东西origin/master
!呸。(这在 git 1.8.4 中已修复;git fetch
现在更新远程分支,即使它写入FETCH_HEAD
.)
6这在 git 1.9 中已修复,这可能最终会成为git pull
一种实际上很方便的便捷方法。:-)