本文的读者需要已经了解 基本的 Git 操作和开发流程。

在我们开发完分支后,一般分支上会有很多 commit —— 少不了诸如 “fix typo”, “sth wrong in the previous commit” 之类的 commit。在合并到主干的时候,往往这类 commit 显得臃肿多余。为了方便别人做 code review,我们希望合并一些不必要的 commit 使我们的分支显得干净一目了然,也方便管理。有 3 种方式可以做到。

一、git rebase

$ git rebase -i origin/master

-i 参数表示互动 interactive,这时 git 会使用你设定的编辑器,让你对 git 历史记录做详细修改。

下面以 Atlassian 的例子来说明

# 开始开发一个新 feature
$ git checkout -b new-feature master
# 改了一些代码
$ git commit -a -m "Start developing a feature"
# 刚刚的修改有点问题,再改一下
$ git commit -a -m "Fix something from the previous commit"# 紧急修复,直接在 master 分支上改点东西
$ git checkout master
# 改了一些代码
$ git commit -a -m "Fix security hole"# 开始交互式地 rebase 了
$ git checkout new-feature
$ git rebase -i master

这时 git 会打开编辑器,你会看到 new-feature 分支上的 2 个最新 commit,以及一些指引提示

pick 32618c4 Start developing a feature
pick 62eed47 Fix something from the previous commit# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

每个 commit 前有一个操作命令,默认是 pick,表示该行被选中,需要进行 rebase 操作。下面一堆注释的指引中还有几个指令,我们常用到的是以下 2 个

  • squash:将这一行的 commit 与上一个 commit 进行合并
  • fixup:与 squash 相同,只是不会保留这行 commit 的提交 message 信息

比如上面的例子,我们在编辑器中修改指令为

pick 32618c4 Start developing a feature
squash 62eed47 Fix something from the previous commit

这样一改,保存执行后,new-feature 分支就只剩下 1 个 commit 了,这个合并后的 commit 提交的信息包含之前 2 个 commit 的信息

Start developing a feature
Fix something from the previous commit

消除了一个多余的不那么重要的 commit,达到了我们的目的。最后,只需 fast-forward merge 到 master

$ git checkout master
$ git merge new-feature

在别人看来,你就是一个天才开发者,没有出差错地一次实现了 new-feature,项目的 commit 历史记录显得干净而有意义。

如果我们在编辑器中不用 squash 指令,而使用 fixup 指令,这样改

pick 32618c4 Start developing a feature
fixup 62eed47 Fix something from the previous commit

则结果一样,还是只剩 1 个 commit,但是合并后的提交消息,就只有之前第一个 commit 的消息,第二个的 commit 消息被注释掉了

Start developing a feature

这样也达到了我们的目的,消除了曾经发生过 2 个 commit 的痕迹。在别人看来,这个新功能的分支是按计划一次性开发好的,中途并未发生 “错别字” 之类的意外,简直完美。

二、–fixup & –autosquash

# 自动标记这一次的 commit 为上一个 commit 的 fix
$ git commit --fixup <commit>
# 自动组织合并两个 commit
$ git rebase -i --autosquash

这种方式和上面的第一种原理是一样的,只是形式上不是在编辑器中调整历史记录,而是直接执行命令,结果等同。

三、撤销过去的 commit 重建一个新的

$ git reset HEAD~2
$ git add .
$ git commit -am "This is the new feature"
$ git push --force

这种方式就比较暴力了,嗯。


说点题外话

修改上一次 commit 提交的 message

有时我们提交代码,message 写的太匆忙有错字(不是代码里有错字,而是 commit message 写错),就可以用下面的命令来修正

$ git commit --amend

不过只能修正上一次的 commit。如果很多个 commit 之前就有 message 写错,就得用上我们之前说的 git rebase 了

$ git rebase -i HEAD~4

和之前一样,会打开编辑器,显示最近的 4 次提交

pick 07c5abd Introduce OpenPGP and teach basic usage
pick de9b1eb Fix PostChecker::Post#urls
pick 3e7ee36 Hey kids, stop all the highlighting
pick fa20af3 git interactive rebase, squash, amend

将 pick 指令改为 reword 指令,就可以修改这一行的 commit message

pick 07c5abd Introduce OpenPGP and teach basic usage
pick de9b1eb Fix PostChecker::Post#urls
reword 3e7ee36 Hey kids, stop all the highlighting
pick fa20af3 git interactive rebase, squash, amend

– EOF –

参考文档

  • 阮一峰:Git 使用规范流程
  • Atlassian Git tutorials: Rewriting history

Git : 合并 commit 保持分支干净整洁相关推荐

  1. git 合并两个分支的某个文件

    软件开发基本都是多个feature分支并行开发,而在上线前有可能某个分支的开发或测试还没有完成,又或者是产品调整,取消了该分支功能的上线计划,我们在release前不合并该分支即可,然而如果该分支中的 ...

  2. git 合并冲突_git分支管理的策略和冲突问题

    备注: 知识点 关于分支中的冲突 分支管理的策略 分支策略 备注: 本文参考于廖雪峰老师的博客Git教程.依照其博客进行学习和记录,感谢其无私分享,也欢迎各位查看原文. 知识点 git log --g ...

  3. Git合并两个分支的步骤

    使用场景: 比如现在有 20190927_Libra.20191021_Scorpio 两个分支. 我们在***20190927_Libra***分支上进行了需求A的开发,又在***20191021_ ...

  4. IDEA GIT 合并commit

    步骤 前提:当前分支在对应commit所在的分支下 打开IDEA的GIT侧边栏,左侧选择本地的分支或者远端的分支,中间将展示提交的commit,右侧将出现每一个commit对应的修改文件 选择要合并的 ...

  5. 【问题解决】git 合并commit 请求报错:Cannot ‘fixup‘ without a previous commit

    1.如果你回不去原分支了,或者无法再次 rebeat,可以按照 git 提示方法先删除,回到原分支使用 checkout 即可.这是小问题. 2.rebeat,不管你是要留下哪些个请求,第一行的 co ...

  6. git合并commit

    查看提交记录 git log 此时想要合并两个"新增人员删除功能" 这里的id要选取到需要合并的前一个 git rebase -i 1832c2438d66f0c4a8a5cb9f ...

  7. 用终端命令(Git)合并到Master分支等操作

    转载于:https://www.cnblogs.com/blance/p/4302992.html

  8. Git 合并时 --no-ff 的作用

    一.场景: 我最近在进行代码合并的时候,使用的是 : git merge --no-ff 分支名称 二.分析 git merge 默认使用的时"快进"(fast-forward)模 ...

  9. git只合并某一个分支的某个commit

    第一种情况:只合并一个commit git checkout develop-hbb git cherry-pick 7c32be61 以上,7c32be61是develop上的一个fix bug的c ...

最新文章

  1. 用数据品鉴咖啡,407杯咖啡数据教你如何区分咖啡等级和风味
  2. 如果我是博客园的产品经理【下】
  3. 华为鸿蒙王者荣耀视频,王者荣耀鸿蒙2.0版
  4. C++ ACM解题
  5. 递归算法之排列组合-求一个集合S的m个元素的组合和所有可能的组合情况
  6. 冒泡排序,swich语句,while循环...基础性的一道综合题初学者可以做一个简单的测试...
  7. Openstack Neutron 管理的网络资源
  8. 电路板上的插头怎么拔下来_空调维修排查电路板内外原因
  9. linux conda创建虚拟环境
  10. python I/O 对象
  11. php不使用插件导出excel
  12. 器件旋转45度_【速评3+1】第十一期:朱雨玲45,日版CL,Rakza Z,国变等
  13. 数字图像处理——图像的统计特征
  14. 关于虚拟机Ubuntu联网问题
  15. MLX90614红外测温模块的使用
  16. awgn信道matlab建模,正交幅度调制信号在AWGN信道中传输的MATLAB仿真
  17. 使用iMX53 IPU SISG功能控制摄像头闪光灯
  18. Java内存模型(JMM)
  19. 机器学习降维方法概括
  20. IC 产品的质量与可靠性测试

热门文章

  1. PopupWindow实现仿iOS QQ音乐上拉菜单栏(支持手势以及点击操作)
  2. Android选择本地视频文件
  3. 方法:如何解决用MFC实现的ping功能中把目标主机不可到达的当成ping通的问题
  4. SonicBoom SFB(short-forwards branch)源码分析
  5. 电脑和云服务器之间怎么传文件,Windows本地环境和Linux腾讯云服务器之间传输文件的方法...
  6. BetaFlight深入传感设计之十:传感器物理特性方向对齐
  7. IDEA2019如何设置字体大小
  8. 關於python 2.x中文字編碼的簡單說明
  9. opencv--python(一)图像和视频处理之读取,显示和保存
  10. Hadoop自学资源