在合并分支的时候,默认是有三种选项的,分别是

  • 普通的 merge
  • squash merge
  • rebase merge

普通 Merge

说到合并分支,可能我们最熟悉的操作是这样的:

  • 先切换到目标分支:git checkout master
  • 执行命令:git merge devel
  • 删除旧分支(可以在上面一同做):git branch -D devel
  • 提交到远程分支:git push origin master

假设合并之前的这样的:

我们这么上述操作之后,分支的 commit 历史将会是这样的:

看上去是一条直直的 commit line,我们在 devel 分支中的 commit 也是一个不差得保留在了 master 中。但是很多时候,我们并不需要那么多的 commit,假设你给一个开源项目提交一个 Bug Fixes,然后一个简单的修改因为你的粗心大意 pull request 了十几个 commit 过去,如果作者给你 merge 了,这就在这个项目的历史长河中增加了十几个 commit 啊,以后的人看 commit history 估计都崩溃了吧;同时,当你 merge 之后发现有问题,想回滚都麻烦。

squash merge

在使用 git 的过程中,可能你遇到过想要合并多个 commit 为一个,然后很多人会告诉你用 git commit --amend,然后你发现里面有你的多个 commit 历史,你可以通过 pick 选择,squash 合并等等。同样得,merge 的时候也可以这么干,你只需要这么简单的两步:

  • 切换到目标分支:git checkout master
  • 以 squash 的形式 merge:git merge --squash devel

你会发现,在 master 分支上居然有未提交的修改,然后你就需要在 master 上主动提交了修改,注意,这里是你 commit 的,也就是改变了 commit 的 author。结果是这样的:


比前面普通的 merge 来说,我们只有一个 commit 了,不管在分支中 commit 了多少,这里都只有一个。

rebase merge

我们既想合并 commits,又想保留作者的信息,那么有没有什么好办法呢?肯定是有的啦,这个时候我们可以尝试一下 rebase,操作步骤是这样的:

  • 先切换到 devel 分支:git checkout devel
  • 变基:git rebase -i master
  • 切换回目标分支:git checkout master
  • 合并: git merge devel

这里完成了第二步之后我想你应该大概知道发生了什么事了,我们在 devel 里面对照 master 进行了变基,所谓的变基其实就是找到两个分支共同的祖先,然后在当前分支上合并从共同祖先到现在的所有 commit,所以我们在第二步的时候会选择怎么处理这些 commit,然后我们就得到了一个从公共commit 到现在的单个 commit,这个时候别人讲我们这个 commit 合并到 master 也只会在 master 上留下一个 commit 记录,就像这样:

虽然这个 commit history 线看上去很不错,而且也比较符合实际情况,但是我们需要注意到的有点就是分支上的开发者需要自己执行变基操作,从而导致他的原始 commit history 变化了(可以理解成被合并了)。

总结

  • rebase 可以保持 master 分支整洁,易于识别 author,容易回滚
  • squash 可以保持 master 分支整洁,但是 master 中 author 都是 maintainer,而不是原 owner,容易回滚
  • 普通merge 不能保持 master 分支整洁,但是保持了所有的 commit history, 回滚时麻烦

操作复杂程度 rebase > squash > 普通merge
回滚复杂度 rebase = squash > 普通merge

在线模拟git 合并,请访问 learn-git-branching

参考资料

  • learn-git-branching
  • merge squash 和 merge rebase 区别

git merge squash 和 rebase 区别相关推荐

  1. git merge\git merge --no-commit\git merge --squash区别

    假设现有分支develop.test.需要将test合并到develop分支. 首先git checkout develop. git merge test test分支会合并到develop,会有t ...

  2. 如何使用git merge --squash?

    我有一个远程Git服务器,这是我要执行的方案: 对于每个错误/功能,我创建一个不同的Git分支 我继续在Git分支中使用非官方的Git消息提交代码 在顶级存储库中,我们必须使用官方Git消息对一个错误 ...

  3. 聊下git merge --squash

    你经常会面临着将dev分支或者很多零散的分支merge到一个公共release分支里. 但是有一种情况是需要你处理的,就是在你的dev的分支里有很多commit记录.而这些commit是无需在rele ...

  4. git merge --squash改写提交

    教程3 改写提交! 7. merge --squash 为了节省时间,这个教程使用现有的历史记录作为本地数据库. 从这里下载 我们移动到stepup-tutorial/tutorial7目录.本地端的 ...

  5. 使用git merge --squash,让commit变得优雅

    阅读本文需要3分钟 情景模拟 我们有三个分支,master,develop以及feature特性分支,假定我们开发时使用的是feature分支,我们来这里查看提交记录 当然,使用IDEA内置的 Ver ...

  6. Git进阶:合并提交记录 git merge --squash

    一.说明 开发分支dev会有很多的commit log,因此如果你在将dev合并到主分支master的时候,在master只想展示一条dev的commit log,让主分支的log看起来很简洁,那么可 ...

  7. git merge和git merge --no-ff有什么区别?

    本文翻译自:What is the difference between `git merge` and `git merge --no-ff`? Using gitk log , I could n ...

  8. git merge origin master和git merge origin/master的区别

    目录 背景 问题 探究 背景 某天同事小L找我帮忙解决代码冲突引起的问题,折腾一番之后,问题解决了.场景是他想把最新的主干分支代码合并到当前开发分支上,解决掉冲突,然后提交推送到远程.他合并代码的过程 ...

  9. git merge --no-ff 和git merge --squash的区别

    区别 不复制粘贴,不讲那么多晦涩难懂的原理.只说实际效果. 我之前一直用squash,但是今天学了一下no-ff,发现这就是我想要的. 如果不加no-ff,合并分支的时候会把你要合并分支的commit ...

最新文章

  1. 【C++11】30分钟了解C++11新特性
  2. python3项目-Python3基础教程(十九)—— 项目结构
  3. python3 练习题100例 (二十二)输入两个字符串,输出两个字符串集合的并集
  4. [Flex]关于国内Flex开发者/从业者的调查问卷
  5. 数据库事务原理详解-事务的嵌套
  6. 国产OS推广应从娃娃和体制内双管齐下
  7. resharper license server
  8. 两台服务器之间mysql数据库怎么做同步_mysql数据库占满磁盘导致服务器无法运行...
  9. testlink匹配mysql8_如何安装Testlink
  10. 解析软件系统稳定性的三大秘密
  11. 英特尔发布年度企业社会责任报告,首次定义“全球性挑战”
  12. C++中和“”引用头文件的区别
  13. DataStore详解
  14. svn 命令行使用总结
  15. 关于 2021 年度「博客之星」评选刷票行为处罚通知
  16. DirectXDirect 3D 游戏开发之3D图形的数学基础
  17. 程序员必备的思维能力:抽象思维
  18. 方差分析(ANOVA)简记
  19. HTML 的静态网页分页样式
  20. 汇编:汇编与C派系语言混用以及对应LLDB常用指令

热门文章

  1. [转]IT人的学习方法
  2. 关于梦想是计算机的作文英语,关于我的梦想英语作文(精选11篇)
  3. Hunter的读《高效程序员的45个习惯》
  4. 壁纸网站:Wallpaper Search: - wallhaven.cc
  5. 改变el-table行高
  6. python+短信宝实现手机短信发送
  7. 易语言 易语言进入下次循环 类似C语言的continue
  8. @Contract注解
  9. 微信支付二维码显示(二)
  10. 安全(Security)设计原则(1)