23 September 2020
号外号外:我的新书《现代JavaScript库开发:原理、技术与实战》出版啦!!!快点我查看
号外号外:一组小而美的JavaScript迷你库!!!快点我查看
号外号外:猿辅导招聘前端,后端,客户端啦!地点:北京!!!快点我查看

rebase是git中一个神奇的命令,可以让并行的提交,变得像线性开发的一样,最近发现rebase在遇到merge commit时可能和认知不太一样,本文通过一个例子来讲解下git rebase遇到merge commit时该如何应对

经典rebase

先来看下rebase的典型使用场景,假设我们有如下一个提交记录

当dev想同步上游(master)的修改时,有两种方案,一种是merge,一种是rebase

merge会创建一个commit节点,并且能够保留分支关系

$ git merge master

但是一般上游到下游的操作,是不需要保留分支关系的,rebase正是为了这个场景设计的,rebase会将dev上的节点,重新在master上重新创建一遍,看起来就是是在master分支最后开发的一样

$ git rebase master

至此就介绍完了rebase常规的使用场景

merge rebase

如果被rebase的分支上有merge commit,会发生什么呢?假设我们有如下的log tree(请原谅我懒得画图了^_^)

* 31ef4ec (HEAD -> master) e
| *   b554f2d (dev) Merge branch 'test' into dev
| |\  
| | * 853aaf6 (test) c
| * | 1af86fa d
| |/  
| * c1b49a5 b
|/  
* 763a350 a

master分支在dev分支后面又有了新的提交,dev分支合并了test分支,现在dev分支想同步master分支,继续使用rebase操作

* 8924fda (HEAD -> dev) c
* 06201b2 d
* e0c6b78 b
* 31ef4ec (master) e
| * 853aaf6 (test) c
| * c1b49a5 b
|/  
* 763a350 a

可以rebase将merge commit抛弃了,同时test分支上的提交c的内容被patch到了dev分支上

这可能和我的认知不太一样,我希望的效果是继续保留merge commit,rebase 为我们提供--rebase-merges参数来这个问题

$ git rebase --rebase-merges master

看下log tree,变基成功了,merge commit被保留了,但test分支也被变基了,test分支上的commit还是被复制了一份

*   88e6cf7 (HEAD -> dev) Merge branch 'test' into dev
|\  
| * e2fae10 c
* | 65869a2 d
|/  
* e61592d b
* 31ef4ec (master) e
| * 853aaf6 (test) c
| * c1b49a5 b
|/  
* 763a350 a

总结

最后建议大家merge和rebase尽量使用一种即可,即rebase的代码,不要包含merge commit;使用了merge操作,就不要在rebase了

参考文档

原文网址:http://yanhaijing.com/git/2020/09/23/git-rebase-merge/

微信公众号:颜海镜
关注微信公众号 颜海镜
微信支付二维码
赞赏支持 微信扫一扫