git pull和git fetch + git rebase有什么区别?

334

另一个问题git pull相当于git fetch + git merge

但是git pullgit fetch+git rebase有什么区别?


2
有人应该清理一下这个链接...而且我对那个其他问题得到了多少票数感到惊讶。 - xenoterracide
13
@xeno:我认为这只是一个计算有多少人也有同样的问题的数量。 - bobobobo
57
有一天我会抽出时间来仔细阅读Git的文档,但在那之前,我会投票支持这类问题。 - Eran Medan
2个回答

371

从你的问题中可以很明显地看出,你实际上只是在问git mergegit rebase之间的区别。

因此,让我们假设您处于常见情况下——您在主分支上完成了一些工作,并从远程仓库"origin"中拉取了一些代码。经过fetch之后,情况如下所示:

- o - o - o - H - A - B - C (master)
               \
                P - Q - R (origin/master)
如果你在这个时候进行合并(git pull 的默认行为),假设没有冲突,你最终得到的结果是这样的:
- o - o - o - H - A - B - C - X (master)
               \             /
                P - Q - R --- (origin/master)

另一方面,如果您进行了适当的变基操作,您将得到以下结果:

- o - o - o - H - P - Q - R - A' - B' - C' (master)
                          |
                          (origin/master)

你的工作树内容应在两种情况下保持相同; 你只是创建了一条不同的历史记录。变基会重写你的历史记录,让它看起来像你是在origin的新主分支(R)上提交的,而不是在最初提交(H)的地方。如果有人已经从你的主分支中拉取了代码,你就不应该使用变基方法。

最后,请注意,你可以通过将配置参数branch.<name>.rebase设置为true来为给定分支设置git pull使用变基而不是合并。你也可以对单个拉取操作使用git pull --rebase


40
如果有人从你的主分支(master branch)拉取过代码后,你执行了 rebase 操作,会发生什么?这会破坏代码库(repo)吗? - Didier A.
14
如何知道有人从你的主分支(master branch)拉取了代码? - Frank
33
如果你不能确定某人没有做某件事,那么你应该假设他们已经这样做了。 - Chris Down
4
我在想,除非您还将更改推送到 origin/master 之外的其他地方,否则我看不出会遇到别人已经拉取所讨论的更改的问题,因为如果您已经将这些更改推送到 origin/master,则首先不需要重新基于。在我看来,警告似乎只在您有比 X -> origin/X 更复杂的情况下才真正重要,但我可能错了。如果有人知道我忽略的情况,请分享。 - neverfox
1
@SteveChambers 不,那不是结果。这些线只是代表提交的系谱关系,即 A 是 B 的父提交。这并不意味着 Q 或 B 中哪个是时间上先提交的。所有这些操作都基于提交图,而不是时间。重新设置基底仅仅移植一些提交,其结果就像我展示的一样,无论提交的时间戳是什么。 - Cascabel
显示剩余11条评论

35

简述:

git pull相当于运行git fetch再运行git merge
git pull --rebase相当于运行git fetch再运行git rebase

针对第一个声明的回答:

git pull相当于git fetch + git merge

“在默认模式下,git pull是git fetch后跟git merge FETCH_HEAD的简写。更精确地说,git pull会使用给定的参数运行git fetch,然后调用git merge将检索到的分支头合并到当前分支中。”

(参考:https://git-scm.com/docs/git-pull)


针对第二个声明/问题的回答:

'但是git pullgit fetch + git rebase之间有什么区别呢?'

同样来自上面的资源:
git pull --rebase

"使用--rebase选项时,它会运行git rebase而不是git merge。"


现在,如果您想问:

'mergerebase之间的区别是什么?'

这也在这里得到了回答:
https://git-scm.com/book/en/v2/Git-Branching-Rebasing(更改版本历史记录方式的差异)


4
我想提一下,“git pull --rebase”大多数情况下类似于“git fetch然后git rebase”- 但并非总是如此。在某些情况下,“git pull --rebase”会做更多的事情。请参阅此经常被引用的示例:https://gitolite.com/git-pull--rebase - Daniel K.
1
非常感谢您的回答。我现在真正理解了git fetch + git rebase命令的工作方式。从现在开始,我们的git树上不再有更多或更少的冲突 :) - Travis Le
1
@DanielK,自从那篇博客文章写出来后不久,git rebase也执行了这些额外的步骤。请参阅git help rebase--fork-point的讨论。 - Buster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接