今天要来分享一个关于merge与rebase的差别。
此为两者的示意图:左为rebase,右为merge。
merge:
首先在master分支上做两次commit,然后再额外创建一个分支feature,并也在其分支上做两次commit,而目前这两个分支是各自独立的,而后我们再到master分支利用git pull将远端的commit更新到local端,并git log ,可看出近两次的commit,已经同步进来。
此时如果我们想将master的commit同步到feature的分支,此时我们利用git checkout feature切换到feature分支,并git log查看,也可发现最近两次的commit,最后我们在利用 git merge master,来将master的commit同步过来。
此时,我们git log发现,master的两次commit已经插入至我们feature两次commit之前,并且再新增一个merge的commit。
如果一定要Push上去的话,可以透过git push (分支名) --force,强制push上去,而去远端Github浏览,可发现commit已经有所改变。
rebase:
再来我们先利用rm rf- /testgit,将原本merge的folder删除,并从远端在重新clone一次,而后进到feature并git log,可看到最新两次的commit。
,发现已变回原本的两次commit。
利用git rebase (要合併进来的branch),可以将其分支的commit插入进来
,而不影响我们原分支的commit,也不会额外产生一个merge的commit,但原分支的hash value会改变
。
假如我们把我们rebase的分支给Push至远端,会发现被rejected,是因为我们通过rebase合併分支,会改变原分支commit的hash value,所以会被rejected。
Summary:
merge:
优点:记录了真实的commit情况
,包括每个分支的详情。
缺点:因为每次merge会自动产生一个merge commit
,所以在使用一些git 的GUI tools,特别是commit比较频繁时,看到分支很杂乱。
rebase:
优点:如果我们今天在master分支不断变化,而我其他分支要去进行同步,但如果用merge就会不断产生merge commit,所以利用rebase可以得到更简洁的专案历史,去掉了merge commit
。
缺点:如果今天有很多人在写同个分支,如果因为rebase造成历史的改变,会影响到每个人分支的使用,合併出现程式码问题不容易定位,因为re-write了history,所以基本上不会对master做rebase
。
通常我们会基于fork或其他分支进行开发,而不会直接用master进行开发
,否则master会很乱,基于分支,大家相互review,降低错误,最后在merge到master,提高质量。