在dev branch上执行下面两个命令,都是为了让dev最新的commits放在master最新的commits之后:
- git merge master
- git rebase master
但是实现的方式有所不同,简单来说,git merge执行了一次三方的提交,所以git merge是非线性的;git rebase并没有进行合并操作,只是提取了当前分支的修改,将其复制在了目标分支的最新提交后面。这些其实都是很虚的话,看一个很有意思的例子:
假设master上有三个提交:a1加了一个文件a.txt, b1加了一个文件b.txt, c1加了一个文件c.txt,如下图:
另外一个开发分支dev3从a1开始分叉,b2也加了不一样的b.txt, c2也加了不一样的c.txt,如下图
当在dev3上执行git merge master时,会冲突,但是一次性展示了所有冲突:
当merge完成后,可以看到b1, b2,c1,c2的commit ID都没有发生变化,只是多了一个5ecece2
但是如果换成rebase的方式,b.txt和c.txt会分别冲突一次,然后再git rebase --continue,如下图
当所有冲突处理完成后,b2和c2的commit ID没有变,b1和a1的commit ID变了,而且中间多git rebase --continue解决了一次从冲突。
因此总结一下,在比较复杂的git管理中:
- 如果只是想简单把dev的最新changes在最新的master上重新演习一下,dev和master改的相同文件较少,git rebase 好
- 如果dev和master改的相同的文件较多,分别的commits也较多,这要分两种情况考虑一下:
- 如果冲突文件在master上比较稳定了,其他人改动较少了,而你的dev又不太完整,还有不少对冲突文件的changes,这个时候建议git rebase。因为在你修改dev一段时间后,还需要再git rebase master,之前改过的冲突就不需要再执行一遍了。这个时候每次拿最新的master都要用git merge master重复地对冲突文件进行重复地修改
- 如果冲突文件已经搅和成一锅粥了,又或者commits较多,又或者对于git新手经常把git rebase的方向搞错,导致dev的提交会比master的提交还靠前,又或者git rebase 需要continue无数次,这个时候建议git merge master一次性看到解决所有冲突文件,解决完冲突尽快merge回master,这种情况下一次次git rebase --continue会崩溃。如果你还有要改的,建议拆分成新的PR。而且和别人同时工作时,尽量少同时改相同文件!!!