Git: 聊聊Rebase命令
相比Merge命令,大家对Rebase要相对陌生一些,Rebase这个命令在《Pro Git book》中被翻译为「衍合」,感觉好别扭,个人感觉无论是从音还是行(为)叫做「变基」要更佳恰当一些。
Rebase的大致流程
这里是的范例参考子《Git Community Book 》后面会附引用地址,需要看详细的可以从文末穿越。
Step1: 场景假定
你基于一个远程分支origin
创建了一个mywork
的分支
git checkout -b mywork origin
Step2: 进行开发
创建好分支后,你就开始兢兢业业的在mywork
分支上开展工作了,一段时间过去,你总共进行了2次提交,这是你去pull一下origin
分支,发现在你工作的同时,别人也没歇着,orgin
分支在这段时间也有了两次提交,如下图:
Step3: 合并分支
发现异同之后,你想在你现在的工作进度上把别人的功能合并过来,这个时候就要涉及到分支合并了,此时你有两个选择,一个是merge
,另一个是rebase
(时刻记住merge与rebase干的是一件事儿),这里我们使用rebase
。
先切换会origin分支,通过pull
指令将origjn
分支上的最新改动拉取下来。然后在用git checkout mywork
切换会mywork
分支,到这里就能用git rebase orgin
来进行变基了。
到这里如果遇到了冲突,终端会给出你提示要求你先去处理冲突,当你把冲突处理完之后,通过git add
确认改动后,不用commit
直接执行git rebase —continue
变基就算完成了。
这里简单说下原理,在你执行「变基」操作的时候,git会将你mywork
分支中的所有新提交撤销commit,并把这些改动临时帮你寄存在.git/rebase
目录下,之后再将清空后的mywork
分支更新到origin
分支状态,最后再把刚才临时帮你保存的变动应用到同步过后的mywork
分支上。这样就起到了「变基」的作用,这种改动是从commit的最后一个公共部分开始的。所以叫「变基」。不过需要重点搞清的两点:
merge和rebase合并后的结果是一模一样的,形象的说,二者是殊途同归。
使用rebase「变基」后的commit与之前没有变基前的commit,即上图中C6’与C6是不同的,它们的SHA-1值不同,Git会把它们看成两次提交。
最后的最后,建议在使用rebase命令时最好能耐心点把命令行提示的信息看完,其实那里面已经包含了一切,而且内容也不多。
Github上Rebase的使用场景
现在社区中推荐的主流Git合作方法,也是利用Rebase命令,即Fork一个代码库后,保留一个remote分支用来跟近主库进度,另开一个feature分支来打patch,当patch大好后,在本地同步一下remote分支上的代码,保持与主库一致,如果在你打patch这段时间,主库发生了变化,那么你就需要在本地预先做一次rebase操作,以保证你的改动是构建在主库最新代码之上的。这其实相当与你帮助作者在本地处理好了冲突,这样作者再合并你的代码时候,也就能比较轻松了。换个角度,其实使用rebase这个过程也是一个自我检查的过程,可以强制你对改动进行Review,从而减轻贡献者和所有者之间的工作量。因为没有人比你更熟悉你的代码。
Rebase与Merge的区别
Git合并分支有两个命令一个是merge,另一个就是rebase,两者最终目的都是一致的,但在一些细节的处理上却大不相同。下图是分别用merge和rebase合并分支后的示意图。可以看出,使用rebase命令合并后的分支呈线性,而用merge后确多处一个分支来,这个小小的差异,其实对最终结果没有影响,仅仅是方式上的差异。
解释 git pull —rebase
git pull —rebase
,这个命令在实际使用中的出场率还是很高的。我们先从git pull
说起,git pull
完整的应该是git fetch
+ git merge FETCH_HEAD
,默认时候git pull
会先拉取代码,再进行merge,上面说了使用merge会多出一条合并的commit
以及一条分支线来,如果commit和merge频繁的话,可能会出现下图这样的情况,但是rebase则不同,其会保持线性,这样提交记录看起来就会整洁许多,使用—rebase
就是这个意思用git rebase
取代git merge
。
下图是使用 git fetch + git merge时间长了的提交记录,这个还不算复杂,你可以在此基础上再往复杂想一下,或者Google一下类似的图。
参考引用
http://dwz.cn/2goS5e
http://dwz.cn/2goSKc