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历史的目的。

关于git rebase -i 的博文:聊下 git rebase -i

熟练使用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 rebase -i

git protocol

git merge 与 rebase的更多相关文章

  1. [git]merge和rebase的区别

    前言 我从用git就一直用rebase,但是新的公司需要用merge命令,我不是很明白,所以查了一些资料,总结了下面的内容,如果有什么不妥的地方,还望指正,我一定虚心学习. merge和rebase ...

  2. git merge 和 rebase 区别

    git pull  超级不推荐使用git pull 有坑,谨慎使用,pull底层是merge git pull 是 git fetch + git merge FETCH_HEAD 的缩写.所以,默认 ...

  3. git merge,rebase和*(no branch)

    上一篇:http://blog.csdn.net/xiaoputao0903/article/details/23933589,说了git的分支,相关的使用方法没说到可是仅仅要google就能搜出一大 ...

  4. 关于git merge,rebase合并的差别,以及*(no branch)的处理。

    1.merge 在上篇介绍分支的时候有简单的说了一下分支的创建和合并,当时合并就是写的merge,这是依据两个不同分支的最后一次提交的commit对象c5,c7和两个分支的交叉点的commit对象c3 ...

  5. Git merge 和 rebase 进一步比较

    但是 假如 我不想看到 分支转折点呢 合并的分支始终会存在一个交叉点 Microsoft Windows [版本 10.0.17134.345] (c) Microsoft Corporation.保 ...

  6. [Git] git merge和rebase的区别

    git merge 会生成一个新得合并节点,而rebase不会 比如: D---E test / A---B---C---F master 使用merge合并, 为分支合并自动识别出最佳的同源合并点: ...

  7. git——merge和rebase的区别

    参考http://www.jianshu.com/p/129e721adc6e 我在公司里看到其他同事都使用git pull --rebase拉取远程代码,而我总是用git pull,也有同事和我说过 ...

  8. git merge与rebase

    参考这篇文章 Git 之 merge 与 rebase 的区别  文章2 另外,使 rebase出现冲突后,先修改冲突,然后git add 某文件(我使用add  .经常有问题),然后git reba ...

  9. git merge 与 rebase 的区别

    http://gitbook.liuhui998.com/4_2.html merge rebase

随机推荐

  1. linux命令指usermod(管理用户以及权限的命令)

    usermod命令:用来修改用户帐号的各项设定. 示例:usermod -a -G usergroupnewuser 或者usermod -aGusergroup newuser 语法:usermod ...

  2. JSP连接MySQL时出现--错误:Access denied for user 'root'@'localhost' (using password: YES)'解决方案

    用代码进行用户验证的时候总是出现这个错误,翻译一下,应该是root用户的是权限的问题没有放开. 那就想办法解决一下吧,具体的来说可以有这样的几种方式. 解决方法,首先想到的是先重启一下MySQL服务吧 ...

  3. Android项目-高考作文-AsyncTask的不足

    1, AsyncTask的不足. 从android4.0开始, 后台只允许一个AsyncTask执行, 如果当前的AsyncTask没有执行完毕, 那么当前的请求一直处于等待状态. 直到上一个执行完毕 ...

  4. 网站开发进阶(三十七)JSP页面跳转问题解决

    JSP页面跳转问题解决 PS:本篇博文质量欠佳,仅供个人学习之用. 前言 在做Web开发时,对别人的应用(jsp+servlet)进行服务器部署时出现了页面跳转无效的情况.但是项目在本地未出现此状况. ...

  5. 【一天一道LeetCode】#98. Validate Binary Search Tree

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...

  6. C++ Primer 有感(标准库set类型)

    set容器只是单纯的键的集合,键必须为一.set容器不支持下标操作,而且没有定义maped_type类型.在set容器中,value_type不是pair类型,而是与key_type类型相同的类型. ...

  7. Linux IPC实践(1) -- 概述

    进程的同步与互斥 进程同步: 多个进程需要相互配合共同完成一项任务. 进程互斥: 由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥;系统中某些 ...

  8. java 运行环境

    1.jre和jdk的区别 jre:java runtime environment, java运行环境,是java程序运行依赖的,包括java的类库的.class文件和kvm. jdk:java de ...

  9. EBS Concurrent Manager(并发管理器)异常处理[final]

    来自:http://blog.itpub.net/35489/viewspace-742191/ 有时候我们在通过 adstpall.sh 关闭应用后,然后再使用adstrtal.sh开启.发现并发 ...

  10. WebStorm开发工具设置React Native智能提示

    最近在做React Native开发的时候,相信大家一般会使用WebStorm,Sublime,Atom等等开发工具.二之前搞前端的对WebStorm会很熟悉,WebStorm最新版是WebStorm ...