git rebase 和 git merge比较

468 阅读3分钟

git merge

catdog以及master这三个分支:

修改cat分支commit add.html,然后执行命令

git checkout master
git merge cat 

本来落后2个Commit的master分支,在进行合并之后,进度也已经跟上cat分支,跟它在同一个Commit上

catdog分支合并

catdog这两个分支都是来自master分支,master不管是要合并cat或是dog分支,Git会直接使用快转模式(Fast Forward)进行合并,说得白一点就是master直接「收割」catdog的成果了。

但如果是catdog这两个分支要互相合并就不一样了,Git会产生一个额外的Commit来处理这件事。一般的Commit只会指向某一个Commit,但这个Commit会指向二个Commit,明确的标记是来自哪两个分支。

cat分支来合并dog分支:

git merge dog 

SourceTree合并后的效果:

git rebase

Git有另一个指令叫做git rebase,也可以用来做跟git merge类似的事情。

从字面上来看,「rebase」是「re」加上「base」,翻成中文大概是「重新定义分支的参考基准」的意思

catdog以及master这三个分支,并且切换至cat分支上。

修改cat commit cat1和dog commit dog0分支

使用git rebase指令来「组合」catdog这两个分开

$ git rebase dog
First, rewinding head to replay your work on top of it...
Applying: add dog0

使用SourceTree查看rebase的历史记录

Rebase合并分支跟一般的合并分支,第一个很明显的区别,就是使用Rebase方式合并分支的话,Git不会特别造成一个专门合并的Commit

Rebase是怎么操作的?

结果来看,感觉像是“把cat分支剪下来,然后贴在dog分支上面”,有点像插花时候“嫁接”的概念, 其实不是太一样,Rebase整个流程是先复制一份然后接入到新的base上去。

取消Rebase操作

回退到合并前的上一个状态 git reset HEAD^ --hard

回退到某个操作

git relog
b08a789 (HEAD -> dog) HEAD@{0}: checkout: moving from cat to dog
e1df166 (cat) HEAD@{1}: checkout: moving from dog to cat
b08a789 (HEAD -> dog) HEAD@{2}: checkout: moving from cat to dog
e1df166 (cat) HEAD@{3}: rebase (continue) (finish): returning to refs/heads/cat     
e1df166 (cat) HEAD@{4}: rebase (continue): add cat1
b08a789 (HEAD -> dog) HEAD@{5}: rebase (start): checkout dog
817fb85 HEAD@{6}: rebase (abort): updating HEAD

以回退到817fb85为例, 执行

git reset --hard 817fb85

使用ORIG_HEAD

在Git有另一个特别的纪录点叫做ORIG_HEAD,这个ORIG_HEAD会记录“危险操作”之前HEAD的位置。例如交替合并或Reset之类的都算是所谓的“危险操作”。透过这个纪录点来取消这次Rebase相对的更简单

 git reset ORIG_HEAD --hard

总结:

使用Rebase来合并合并的好处,就是它不像一般合并可能会产生额外的合并专用的Commit,而且历史顺序可以按照谁Rebase谁而决定;对不熟悉Rebase的人来说是个垃圾,解决冲突也是一大问题。

参考: git-scm.com/book/zh/v2/…

zhuanlan.zhihu.com/p/44857713

juejin.cn/post/684490…

www.cnblogs.com/xueweihan/p…