如何优雅地使用 Git - 掘金
https://juejin.im/post/5a54386af265da3e3b7a6317
如何和产品妹子解释什么是变基
https://mp.weixin.qq.com/s?__biz=MzA3ODUxMjMyMw==&mid=2649753261&idx=1&sn=091ab93c0e15f02c7d8d45cf634a8820#rd
你会在 WebIDE 里变基么?
https://mp.weixin.qq.com/s?__biz=MzA3ODUxMjMyMw==&mid=2649753249&idx=1&sn=0e60ecb1d128696e6323552b082471ef&scene=21#wechat_redirect
git rebase vs git merge详解 - 世有因果知因索果 - 博客园
https://www.cnblogs.com/kidsitcn/p/5339382.html
git merge 和 git rebase 小结 - CSDN博客
http://blog.csdn.net/wh_19910525/article/details/7554489
在开发过程中使用git rebase还是git merge
https://www.zhihu.com/question/36509119
Git Rebase原理以及黄金准则详解 - 某熊的全栈之路 - SegmentFault 思否
https://segmentfault.com/a/1190000005937408
Elpie Kay
不管用什么风格的操作流程来整合你的本地分支,最终,这条分支是要和服务器上的目标分支做一次merge的。
通常情况下有这么两种情形:
2.本地分支A-B-C-D,服务器上是A-B-E。这时候直接push,假如设置允许这次push并且没有冲突的话,那最终服务器上会是A-B-分叉:一边是C-D,一边是E,然后E和D又连到一个新的merge commit F上。优点:记录下合并动作;缺点:很多时候这种合并动作是垃圾信息,记录意义不大,反而把历史树搞得复杂不直观,会对实际工作带来负面作用。
负面作用实例:某工在push完提交以后,想用当前分支最新的代码编译一个版本,于是就在D上打了个tag,因为他想D是最新的一笔提交嘛,然后让编译job根据这个tag去抓代码编译了,编完后同事跑来跟他反馈说,这版本不对呀,我改的E好像没起效果嘛。我比你先push的,你说你取了最新的代码,怎么会没有我的改动呢?
某工应该把tag打在F上,才能取到当时最新的版本。他在取版本时不用tag而是用branch,那是可以避免这种情况的,因为branch一般指向的commit就是最新的。但也存在风险:job去取分支时,分支上又被其他人上了新的提交,这个新提交很可能并不是他想要的,还可能带来不好的副作用。如果先处理一下,使得最终提交是像第1种情形里的那样,那tag打在D上是没有问题的。
那某工在提交之前,如果先做一次rebase。git pull --rebase,那么本地分支就会被更新成A-B-E-C’-D’,把C-D的基从B上变到E上,这时再去push,那服务器上也变成A-B-E-C’-D’. 那tag打在D’上就行了。目标分支上的历史树还是一条线。
当然他也可以先在本地merge。默认情况下git pull origin 远程分支,会把远程分支上的E更新到本地,然后merge到本地分支上。merge结束后,本地最新的一个commit就是F,某工可以清楚地知道现在最新的commit是F而不是D,tag也不会建错。这时再push,那服务器上也会进行快进式合并,目标分支也会更新到F上。但历史树不是一条线了,中间有分叉然后又合并到一起。
这种有分叉的历史树还是有一个优点,D和E分别代表了某工和同事各自的版本,D上不包含E的改动,E上不包含CD的改动。而一条线的话,D’是包含了E的改动的,而E不包含C’D’。此时如果想要D的版本(不包含E),那得把D找出来,建个tag或者branch引用起来;或者在D’后面把E的改动revert掉。
其它可能还有一些情形,但大致上会是第二种情形的变形。rebase和merge的使用得看具体的情形,并不存在谁比谁好。rebase和merge比起来,相对难以理解和使用一些。在学习rebase的过程中,可以把它分解成cherry-pick来做。
git cherry-pick用法 - 简书
https://www.jianshu.com/p/d577dcc36a08
Git cherry-pick - 小白搞技术 - 博客园
https://www.cnblogs.com/yangweiqiang/p/6958464.html