设为首页 收藏本站
查看: 1087|回复: 0

[经验分享] Git Step by Step – (8) Git的merge和rebase

[复制链接]

尚未签到

发表于 2018-1-15 15:49:35 | 显示全部楼层 |阅读模式
  前面一篇文章中提到了"git pull"等价于"git fetch"加上"git merge",然后还提到了pull命令支持rebase模式,这篇文章就介绍一下merge和rebase之间有什么差别。
  由于我们主要是想看看merge跟rebase之间的区别,这里就是用本地仓库的分支进行演示了。
merge
  其实在介绍分支的那篇文章中已经介绍过了一些分支merge的内容,这里就进行一些补充和总结。
  下面我们基于本地一个仓库开始介绍,当前仓库的分支情况如下:

  其实,merge命令总结下来会有三种情况发生:

  • merge命令不生效  当目标分支是当前分支的祖先commit节点,也就是说当前分支已经是最新的了,在这种情况下merge命令没有任何效果。
      在当前仓库中,当我们把dev分支merge到master的时候,会得到"Already up-to-date."

  • Fast-forward合并模式  当前分支是目标分支的祖先commit节点时,会发生Fast-forward的merge,看下图

      这时的对象模型就更新了,这里merge的操作只是把dev分支的HEAD引用进行更新,指向最新的commit对象

  • 三方合并  请参照"Git Step by Step – (5) Git分支(branch)"中分支合并的内容。如果没有冲突,Git会帮我们完成分支的合并,如果有冲突,就需要我们手动解决冲突了。
Fast-forward合并模式
  在前面我们看到了Fast-forward合并模式,这种合并模式很简单,只是HEAD引用的更新。但是合并后,我们从"git log"中将看不到分支的信息。

  在Git中,我们可以选择在merge的时候禁止Fast-forward。现在,我们通过"git reset --hard HEAD~1"撤销前面的Fast-forward合并。
  然后,我们在merge命令中加上"--no-ff"进行合并操作。

cherry-pick
  这里我们将插入介绍一个非常有用的命令,虽然它跟merge没有什么关系。
  在实际应用中,我们可能会经常碰到这种情况,在分支A上提交了一个更新,但是后来发现我们同样需要在分支B上应用这个更新。那么这时cherry-pick就可以帮助你解决问题。
  我们要做的就是通过"git reflog"找到A上那个更新的SHA1哈希值,然后切换到B分支上使用"git cherry-pick"。

  当我们手动合并过冲突,然后继续执行"cherry-pick"时候,Git会给出友好的交互界面,如果我们不需要更新这个提交的message,我们可以直接":wq"进行保存退出。到此,这个"cherry-pick"操作就成功了。

rebase
  前面我们介绍了merge,现在来看看rebase。在merge的过程中,比较好的就是我们可以看到分支的历史信息,但是,如果分支很多的时候,这个分支历史可能就会变得很复杂了。如果我们使用rebase,那么提交的历史会保持线性。
  rebase的原理:先将当前分支的HEAD引用指向目标分支和当前分支的共同祖先commit节点,然后将当前分支上的commit一个个apply到目标分支上,apply完以后再将HEAD引用指向当前分支。是不是有点绕,下面我们看个实例。
  下面就开始rebase的介绍,我们会基于master新建一个release-1.0的分支,并在该分支上提交一个更新。

  这时,我们在release-1.0分支上执行"git rebase master",就会得到下面的对象关系图。

  根据rebase的工作原理进行分析:

  • 把当前分支的HEAD引用指向"00abc3f"
  • 然后将当前分支上的commit一个个apply到目标分支,这里就是把"ed53897"更新apply到master上;注意,如果没有冲突,这里将直接生成一个新的更新
  • 最后更新当前分支的HEAD引用执行最新的提交"8791e3b"

  这个就是rebase操作,可以看到通过rebase操作的话,我们的commit历史会一直保持线性。在这种情况下,当我们切换到master分支,然后进行"git merge>  当然rebase操作也会产生冲突,当一个冲突发生的时候,我们可以skip过当前的patch(一定要当心,不要随便使用,以免丢失更新);也可以手动的解决冲突,然后继续rebase操作

rebase交互模式
  其实,rebase还有别的很强大功能,比如rebase交互模式,通过交互模式我们可以改变commit的信息,删除commit,合并commit以及更改commit的顺序等等。
  假如我们现在想要更新一个commit的信息,我们就可以使用rebase交互模式,找到commit的哈希值,然后进入交互模式。

  根据rebase的操作提示,我们选择edit操作,然后保存退出。

  这时,Git将会提示我们,是进行更改,还是可以继续操作。这里我们通过"git commit --amend"进入编辑模式。

  在编辑模式中对commit进行更新,然后保存退出,继续rebase操作。

  关于rebase交互模式的其他命令,这里就不做介绍了,有兴趣的同学可以google一下。
总结
  这篇文章主要对merge和rebase进行了介绍。对于最终的结果而言,rebase和merge是没有区别的,不会发生rebase和merge导致最终更新不一致的情况。
  rebase和merge的差别主要是:

  • rebase更清晰,因为commit历史是线性的,但commit不一定按日期先后排,而是当前分支的commit总在后面(参考rebase原理)
  • merge之后commit历史变得比较复杂,并且一定程度上反映了各个分支的信息,而且 commit按日期排序的。
  大家可以根据自己的项目需求进行选择使用哪种方式拉取远程的更新。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-435373-1-1.html 上篇帖子: Git 常用命令详解(二) 下篇帖子: 在Android Studio 和 Eclipse 的 git 插件操作 "代码提交"以及"代码冲突"
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表