git merge
有cat,dog以及master这三个分支:
修改cat分支commit add.html,然后执行命令
git checkout master
git merge cat
本来落后2个Commit的master分支,在进行合并之后,进度也已经跟上cat分支,跟它在同一个Commit上
cat和dog分支合并
cat跟dog这两个分支都是来自master分支,master不管是要合并cat或是dog分支,Git会直接使用快转模式(Fast Forward)进行合并,说得白一点就是master直接「收割」cat或dog的成果了。
但如果是cat跟dog这两个分支要互相合并就不一样了,Git会产生一个额外的Commit来处理这件事。一般的Commit只会指向某一个Commit,但这个Commit会指向二个Commit,明确的标记是来自哪两个分支。
cat分支来合并dog分支:
git merge dog
SourceTree合并后的效果:
git rebase
Git有另一个指令叫做git rebase,也可以用来做跟git merge类似的事情。
从字面上来看,「rebase」是「re」加上「base」,翻成中文大概是「重新定义分支的参考基准」的意思
有cat,dog以及master这三个分支,并且切换至cat分支上。
修改cat commit cat1和dog commit dog0分支
使用
git rebase指令来「组合」cat跟dog这两个分开
$ 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的人来说是个垃圾,解决冲突也是一大问题。