1. git merge
  2. git rebase
  3. merge V.S. rebase
  4. 参考材料

写在开始:

对merge和rebase的用法总有疑惑,好像两个都能完成“获取别的branch的commits到我的branch上”,那二者的区别又是什么。通过一些文章和实验,整理如下,参考资料附后。


1.git merge

来看两种场景中merge的不同方式。

  • 场景一:切出特性分支后,develop分支上没有新的提交。

fast-forward,若无分歧,会直接移动文件指针。看不出特性分支的起始点。

no-fast-forward(--no-ff),保留提交链的完整性。

squash,压缩不必要的commit;无法看出feature分支合到develop;feature,develop保持相对独立。

  • 场景二:切出特性分支后,develop分支上提交了C6,C7。

                  

develop分支上提交了C6,C7,无法fast forward。

three way merge,

    1. 找到develop分支的最新节点C7;
    2. 找到feature分支的最新节点C5;
    3. 找到develop分支和feature分支的共同祖先节点C3;
    4. 对C3,C5,C7进行三方合并,生成最新的C8。

2.git rebase

变基/衍合,从旧的base变基到新的base,在新base的基础上重现另一个分支的修改过程,版本树像两个链条串在一起变成一个链条,以达到线性的效果。

rebase,对指定的base本身并没有什么影响;只是重写base之后的commit历史。

来看几个场景:

  • 在继续开发的过程中和主分支develop同步

从develop上拉出分支做一些开发工作,在这个过程中develop分支可能继续往前走了,那我们需要经常和develop保持下同步(可能是别人提交了公用的模块,或者修复了对大家都有影响的bug)。之前我会通过pull操作来达到这一目的,但pull往往内置了merge(pull的效果看起来就像fetch+merge,想想提到过的“merge应该反映业务层面的合并,而非技术行为”,并且此时merge会产生一些杂乱的历史记录)。

这就相当于我们本地的开发工作(一系列的commits)是在旧的base上展开的,应该使用rebase操作,将本地的开发工作变基到develop的最新节点上。

git pull --rebase

  • 重新拾起搁置的工作

很久之前可能启动一个并行工作(开发不着急上线的新特性或者优化一些功能),但一直没有时间处理所以就搁置了,现在又有时间重新拾起,然后就发现当时基于的base实在是太太太老了。现在肯定是希望基于最新的base展开工作,这样就可以从已解决的bugfix或已完成的新特性中中受益。

  • 在push之前整理我的本地历史
git rebase -i <myBaseCommit>

这是一个使用更频繁的场景:并不是为了变基,而是清理本地的commit。很多情况我们都需要commit:

    • 可能需要多个连续的commit才能完成一次bugfix;
    • 切换分支需要保存本地修改(当然按理说这个时候应该使用stash或者idea提供的shelve了);
    • 某些历史commit写错了msg(最近一次commit的msg可以通过 commit --amend 修改);

通过-i(--interactive,交互式的),我们可以干预rebase将要执行的脚本化过程,从而达到清理本地commit历史的目的。

熟练使用rebase,可以轻松的进行commit,只需要在最终push之前做一次清理,不必担心影响到公共仓库。

git fetch origin develop
git rebase origin/develop
... do sth ...
git push
  • rebase的场景和用法还有待探索,慢慢更新了。

记住这个:

只能rebase私有分支,一旦发布到公共仓库,不要再rebase了。


3.merge V.S. rebase

什么时候用merge;基于上述不同的merge行为(fast-forward,--no-ff,squash),什么场景下用哪种merge:

merge执行一个合并,这个合并应该反应业务层面的合并,而非技术行为。我们希望在当前分支上往前走,这样它就包含了其他分支的工作。

所以问题的关键是:这个“其他分支”是什么样的分支?这个“其他分支”需要在历史图谱中展示么?

  • 本地的、临时的分支,使用它仅仅是为了使master保持clean。

1.若拉出本地分支后,master往前走了,此时在本地分支:

git rebase -i master

将本地分支变基到最新的master节点(重新梳理本地历史提交信息比如合并成一个commit),好似本地分支就是在最新的master节点上做的开发工作,以保证合并到master后呈现线性增长。

2.在master上:

git merge (fast-forward)

最终以一个或几个commit展现在master上。

  • 知名分支,团队明确定义的,可能是用来追踪bug/feature。

永远不要用rebase,而是用

git merge --no-ff

以保留清晰完整的历史图谱。


4.参考材料

GETTING SOLID AT GIT REBASE VS. MERGE

git rebase vs git merge详解

Git team workflows: merge or rebase?

git随笔集

git merge的几种形式

A successful Git branching model

git merge 与 git rebase的更多相关文章

  1. Git merge 与 git rebase的区别

    Git merge的用法: git merge Dev // Dev表示某分支,表示在当前分支合并Dev分支 git merge -m  "Merge from Dev"  Dev ...

  2. git merge与 git rebase区别及实例

    接Git分支创建与合并,在分支合并时,有两种方式:git merge 和git rebase. git merge:将两个分支,合并提交为一个新提交,并且新提交有2个parent. git rebas ...

  3. git第七节---git merge和git rebase

    # git merge和git rebase 都可以进行分支合并 #git merge 合并后保留记录两个分支的记录 #git rebase合并后会展示成一个分支的记录,另一个分支的提交实际生成了一个 ...

  4. git merge和git rebase的区别

    git merge是用来合并两个分支的.# 将b分支合并到当前分支git merge b git cherry-pick可以选择某一个分支中的一个或几个commit(s)来进行操作.例如,假设我 们有 ...

  5. git merge和git rebase的区别和异同

    1.git  merge和git rebase作用差不多,都是将远程代码和本地代码合并 2.git  merge和git rebase作用差不多,都是将远程代码和本地代码合并 3.git  merge ...

  6. git merge 及 git rebase的区别

    Git上合并代码有git merge 及 git rebase 两种方式. 前置知识点 Master分支:首先,代码库应该有一个.且仅有一个主分支.所有提供给用户使用的正式版本,都在这个主分支上发布. ...

  7. 【译文】Git merge 和 Git rebase比较

    [译文]Git merge 和 Git rebase比较 原创: 胡江华 胡同学和朋友们的成长日记 2017-03-22 git rebase 这个命令经常被人认为是一种Git巫术,初学者应该避而远之 ...

  8. git merge 与 git rebase的区别?

    一,git merge 与 git rebase的区别 1,git merge 例如: master分支合并dev分支,git将两个分支dev和master上的所有commit , 按照提交时间的先后 ...

  9. git pull、git fetch、git merge、git rebase的区别

    一.git pull与git fetch区别 1.两者的区别       两者都是更新远程仓库代码到本地. git fetch相当于是从远程获取最新版本到本地,不会自动merge. 只是将远程仓库最新 ...

  10. git merge 和 git rebase 小结

    Git merge是用来合并两个分支的. git merge b # 将b分支合并到当前分支 同样 git rebase b,也是把 b分支合并到当前分支 ---------------------- ...

随机推荐

  1. JAVA之旅(二十九)——文件递归,File结束练习,Properties,Properties存取配置文件,load,Properties的小练习

    JAVA之旅(二十九)--文件递归,File结束练习,Properties,Properties存取配置文件,load,Properties的小练习 我们继续学习File 一.文件递归 我们可以来实现 ...

  2. 漫谈android系统(4)bring up panel

    点击打开链接 版权声明: 作者:alex wang 版权:本文版权归作者和CSDN共有 转载:欢迎转载,为了保存作者的创作热情,请按要求[转载],谢谢 要求:未经作者同意,必须保留此段声明:必须在文章 ...

  3. CentOS上PHP完全卸载

    想把PHP卸载干净,直接用yum的remove命令是不行的,需要查看有多少rpm包,然后按照依赖顺序逐一卸载. 1.首先查看机器上安装的所有php相关的rpm包 [root@localhost ngi ...

  4. Hash存储机制 - HashMap原理 HashSet原理

    HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,其中 HashMap 是 Map 接口的常用实现类,HashSet 是 Set 接口的常用实 ...

  5. Cracking the Coding Interview:: 寻找有环链表的环路起始节点

    给定一个有环链表,实现一个算法返回环路的开头节点. 这个问题是由经典面试题-检测链表是否存在环路演变而来.这个问题也是编程之美的判断两个链表是否相交的扩展问题. 首先回顾一下编程之美的问题. 由于如果 ...

  6. Linux 学习笔记_12_文件共享服务_4_SSH

    SSH文件共享服务 一.ssh远程登录[一般的Linux系统都会默认安装并启用] 1.Linux上远程命令行登录:ssh 用户名@远程主机IP地址 常用选项: -2:表示SSH2,强制使用第二代SSH ...

  7. 基于Retrofit2.0+RxJava+Dragger2实现不一样的Android网络构架搭建(转载)

    转载请注明出处:http://blog.csdn.net/finddreams/article/details/50849385#0-qzone-1-61707-d020d2d2a4e8d1a374a ...

  8. 开源电子商务平台:OfBiz

    OFBiz是一个电子商务平台,是一个非常著名的开源项目,提供了创建基于最新J2EE/XML规范和技术标准,构建大中型企业级.跨平台.跨数据库.跨应用服务器的多层.分布式电子商务类WEB应用系统的框架. ...

  9. 循环链表设计与API实现

    基本概念 循环链表的定义:将单链表中最后一个数据元素的next指针指向第一个元素 循环链表拥有单链表的所有操作 创建链表 销毁链表 获取链表长度 清空链表 获取第pos个元素操作 插入元素到位置pos ...

  10. SpriteBuilder中子节点的相对位置(%百分比定位)

    子节点(或在这里确切的为精灵sprites)50%的偏移效果使得其在父节点中居中显示,该父节点的纹理在左下角(锚点为0,0). 这样做好过用父节点的位置的实际值来定位.根据父节点实际位置来定位在早期的 ...