git rebase upstream/master和git pull --rebase upstream master的区别

62
git rebase upstream/mastergit pull --rebase upstream master之间有什么区别,如果有的话是什么?远程分支可以是任何分支,不一定是upstream。
1个回答

68

git pull --rebase会首先获取 (git fetch),更新upstream/master提交。

如果你只是重新设置基础版本(rebase)而没有首先更新upstream/master,那么你将得不到相同的结果。

我在“master分支和'origin/master'分叉了,如何使它们不再分叉?””中进行了说明。


SnakE在评论中提到,git pull --rebase并不完全等同于git fetch && git rebase origin/master。请参见 "“git pull --rebase”是什么意思?"。

(origin/master)
   |
A--B--C (master)
 \ 
  B'--D (actual origin/master after changing B and force pushing)

git pull --rebase在这种情况下的作用是:

git fetch origin
git rebase --onto origin/master B master

这里:

  • origin/master 是新更新的 origin/master (B')
  • B 是旧的 origin/master(在 fetch 更新之前)
  • master 是要在 origin/master 之上重新播放的分支

这与使用 git fetch + git rebase origin/master 不同,因为 pull --rebase 命令试图找出哪些提交是你本地的,哪些是之前从上游获取的。

为了做到这一点,它会查看远程跟踪分支的reflog(在本例中为origin/master)。该reflog代表了对origin进行连续git fetch操作的提示,按“最新的在前”的顺序排列。
对于每个reflog条目(先是origin/master@{1},然后是...{2}等),它会检查该提交是否是当前分支头master的祖先。只要找到一个,它就选择它作为rebase的起点(如上面的B)。

14
git pull --rebase upstream master 相当于 git fetch upstream && git rebase upstream/master,两者类似。 - Dennis
6
实际上不是这样的。想象一下你提取了历史记录 A-B 并在其之上进行更改,形成了 A-B-C。然后另外一个人对 B 进行了修改,变成了 B' 并强制推送他们的更改,因此源变成了 A-B'-D。如果您执行 git fetch && git rebase origin/master,重新设置基准会失败并产生冲突。但是 git pull --rebase 将解决冲突,并最终生成 A-B'-D-C。在 pull --rebase 中肯定有一些神奇的事情正在发生。编辑:证明链接 - SnakE
@SnakE 很好的观点,谢谢你。我已经在答案中包含了 pull --rebase 算法以增加可见性。 - VonC
2
神奇的功能可以直接在 git merge-base --fork-point 中使用。 - jthill
@jthill,自从我在那里记录fork-point以来,我假设已经有1.9.0+了:https://dev59.com/D2855IYBdhLWcg3w6IzV#20423029 - VonC
显示剩余2条评论

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