但行好事
莫论前程❤

Git合并命令 rebase 和 merge 的区别

Description

​ git rebase 和 git merge 一样都是用于从一个分支获取并且合并到当前分支,但是他们采取不同的工作方式,以下面的一个工作场景说明其区别

场景:

如图所示:你在一个feature分支进行新特性的开发,与此同时,master 分支的也有新的提交。

img

为了将master 上新的提交合并到你的feature分支上,你有两种选择:merging orrebasing

merge

执行以下命令: 将master 上新的提交合并到你的feature分支

git checkout feature
git merge master

或者执行更简单的:

git merge master feature

那么此时在feature上git 自动会产生一个新的commit(merge commit) look like this:

img

merge特点:自动创建一个新的commit
如果合并的时候遇到冲突,仅需要修改后重新commit
优点:记录了真实的commit情况,包括每个分支的详情
缺点:因为每次merge会自动产生一个merge commit,所以在使用一些git 的GUI tools,特别是commit比较频繁时,看到分支很杂乱。

rebase

本质是变基 变基 变基
变基是什么? 找公共祖先
共同祖先是什么? 详见参考资料2、3官方的文章

执行以下命令:

git checkout feature
git rebase master

look like this:

img

rebase 特点:会合并之前的commit历史

​ 优点:得到更简洁的项目历史,去掉了merge commit

​ 缺点:如果合并出现代码问题不容易定位,因为re-write了history

rebase 是什么情况呢?还是一个初始的仓库历史图:

img

​ rebase初始仓库历史

​ 如果是在 master 分支上 git rebase deve:Git 会从两个分支的共同祖先 3311ba0 开始提取 master 分支(当前所在分支)上的修改,即 85841bea016f64e53ec51,再将 master 分支指向 deve 的最新提交(目标分支)即 35b6708 处,然后将刚刚提取的修改依次应用到这个最新提交后面。操作会舍弃 master 分支上提取的 commit,同时不会像 merge 一样生成一个合并修改内容的 commit,相当于把 master 分支(当前所在分支)上的修改在 deve 分支(目标分支)上原样复制了一遍,操作完成后的版本历史就像这样:

img

​ rebase 合并图

​ 可以看见 master 分支从 deve 分支最新提交 35b6708 开始依次提交了自己的三个 commit(由于是提取修改后重新依次提交,故 commit 的 hash 码与上面的85841bea016f64e53ec51 不同)

合并时如果出现冲突需要按照如下步骤解决

  • 修改冲突部分
  • git add
  • git rebase --continue
  • (如果第三步无效可以执行 git rebase --skip

不要在git add 之后习惯性的执行 git commit命令

merge 和 rebase 冲突处理策略的不同

  • merge 遇见冲突后会直接停止,等待手动解决冲突并重新提交 commit 后,才能再次 merge
  • rebase 遇见冲突后会暂停当前操作,开发者可以选择手动解决冲突,然后 git rebase --continue 继续,或者 --skip 跳过(注意此操作中当前分支的修改会直接覆盖目标分支的冲突部分),亦或者 --abort 直接停止该次 rebase 操作

The Golden Rule of Rebasing rebase的黄金法则

never use it on public branches(不要在公共分支上使用)

比如说如下场景:如图所示

img

如果你rebase master 到你的feature分支:

​ rebase 将所有master的commit移动到你的feature 的顶端。问题是:其他人还在original master上开发,由于你使用了rebase移动了master,git 会认为你的主分支的历史与其他人的有分歧,会产生冲突。

所以在执行git rebase 之前 问问自己,

会有其他人看这个分支么?

​ if YES 不要采用这种带有破坏性的修改commit 历史的rebase命令

​ if NO ok,随你便,可以使用rebase

Summary 总结

如果你想要一个干净的,没有merge commit的线性历史树,那么你应该选择git rebase
如果你想保留完整的历史记录,并且想要避免重写commit history的风险,你应该选择使用git merge

赞(2) 打赏
未经允许不得转载:刘鹏博客 » Git合并命令 rebase 和 merge 的区别
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏