作者 | Michael Müller
译者 | 弯月
出品 | CSDN(ID:CSDNnews)

提出和接受反馈是代码审查不可或缺的一部分。虽然反馈有助于减少 bug 的数量,而且还能提高代码的可维护性,但这个过程也有很多难点。接受批评可能会很困难,而且还会导致团队紧张。然而,在文本中,我们想讨论一下处理反馈的技巧。我们希望找出实现代码变更请求的最佳方式。

在提出合并请求后,被要求修改代码时,你有两种选择。这两种方法都有各自的优缺点。

追加新的提交

追加新的提交非常简单快捷。因为你可以根据每个变更请求创建一个提交,这样审查者就可以了解到你针对他们提出的反馈做了怎样的处理。这种方法的缺点是,git 历史记录不太整洁。

整洁的 git 历史记录不仅仅关系到拥有更好的 git 日志输出。随着时间的推移,项目会不断发展,变得越来越复杂,整洁的 git 历史记录有助于我们查明导致某个 bug 的原因。我们会使用 git bisect 来找出哪次变更破坏了代码(更多信息,请参阅 git 用户手册或 git bisect)。

只有当你确信每个提交都能正常工作时,这种方法才有效。因此,包含有可能破坏代码的提交会非常讨人厌。最终你有可能得到错误的结果,或者你必须跳过某些提交。

避免这个问题的一种方法是在合并代码时,压缩提交。对于只有一个初始提交的小型合并请求来说,这种方法尤其奏效。当代码变更越来越大时,你可以将它们分组成多个小型的逻辑提交。这不仅可以提高 git bisect 结果的准确度,而且还可以加快代码审查。但是,在合并期间压缩提交会降低生产率,因为所有代码都会变成一个巨大的提交。

修改现有的提交

为了避免上述缺点,你可以在原始提交中处理反馈意见。这种方法需要更多的时间,而且需要熟练掌握 git。

如果你是 git 新手,可能很难搞清楚如何简单地编辑现有提交。如果你的合并请求只包含一个提交,则可以将 git commit -m “…” 换成 git commit–amend 即可。如何你是在最后一次提交或之前的提交的基础之上进行第二次修改,那么情况就会更复杂。
一种方法是使用交互式 rebase(git rebase -i base_branch),并标记要编辑的提交。有关如何执行此操作,你可以参考一些文章或查看 git 用户手册。

虽然这种方法非常强大,而且还可以通过各种方式修改 git 历史记录,但这并不是最快的修复提交的方法。

结合两种方法:fixup 提交

git有一个鲜为人知的功能,你可以结合以上两种方法。你可以创建新的提交来修复代码,同时还能得到一个整洁的 git 历史记录。我指的就是 fixup。这种提交带有特殊的提交消息,告诉 git rebase 将代码变更分别合并到各自的原始提交中。如果你从未听说过这个命令,也不用感到惊讶。git 手册并没有提到这个命令,而且其他文档也未能很好地解释这个特性。下面,我们就来看看如何使用这个命令。

在这个示例中,我们将设法修复如下 git 历史记录(git log --oneline):

29a0f49 (HEAD -> feature-branch) good commit54a0517 broken commit00eecd3 (master) initial commit

假设我们需要修复的提交名为“broken commit”。第一步,像往常一样修改代码,并保存到预发布环境(gitadd -u -p)。在提交这个变更时,我们不写提交消息,而是通过 git commit --fixup54a0517 告诉 git 创建修复提交。新建的 git 提交如下所示:


c1e7149 (HEAD -> feature-branch) fixup! broken commit
29a0f49 good commit
54a0517 broken commit
00eecd3 (master) initial commit

为了获得整洁的 git 历史记录,我们需要执行 git rebase -i --autosquash,将变更后的代码重新合并到各自的原始提交。git 会显示执行 rebase 命令的经过。除非你想手动修改历史记录的其他部分(例如提交消息),否则只需关闭编辑器即可。查看 git log --oneline,你就会注意到完全没有 fixup 提交的痕迹:

8f15489 (HEAD -> feature-branch) good commit
079dc70 broken commit
00eecd3 (master) initial commit

git历史记录与第一个完全相同,只不过哈希由于 rebase 而改变了。

上述只是一个非常基本的示例,展示了如何使用 fixup 提交。在实际的工作中,你可能会有多个 fixup 提交,甚至可能都是针对同一个原始提交。

fixup 提交是终极解决方案吗?

fixup 提交是整合反馈的好方法,但这种也有其局限性。如果提交之间相互依赖,或编辑相同的代码区域,则 git 可能无法自动将修复重新合并到已有的提交中。

最终你不得不再次使用交互式rebase 一步步执行 git 历史记录。不过,根据我自己的经验,很多时候使用 fixup 提交都没问题。不过,这就需要保证你们的代码都是很小的原子提交,而且你需要按照特定的顺序进行操作,比如移动代码块,只有这样 git 才能轻松地重新定位原始提交。

另一个可能出现的问题是,一不小心创建有可能破坏代码的提交。如果将变更 rebase 到了错误的提交,虽然 rebase 的运行会成功,但生成的代码可能是错误的,例如调用在未来的提交中才会定义的函数。

幸运的是,git 提供了这个问题的解决方案。我们可以告诉 git rebase 在每次提交时执行某个命令,如果遇到非零退出代码,则停止执行命令。这样我们就可以在提交过程中编译代码或运行测试。如果你想在每次提交时运行 make test,则可以尝试如下命令:git rebase --exec"make test" base_branch。

此外,你还可以将这两个命令结合起来 gitrebase -i --autosquash --exec “make test” base_branch,如果有任何问题立即就可以注意到。注意:git bisect 也支持这个功能。如果你能编写脚本/程序来检测 bug,就可以完全自动化 bisect。

fixup 提交的工作流程仍有一个小麻烦。你仍然需要手工查找提交的哈希或引用,并提供给 git commit --fixup,这多少有点麻烦。有很多包装器可以解决此类问题,例如git-fixup、git-autofixup 或 git-absorb。

参考链接:

  • https://mergeboard.com/blog/3-code-review-feedback-fixup/

代码审查反馈提交修复时,是否应该压缩提交?相关推荐

  1. jquery+bootstrap实现tab切换, 每次切换时都请求数据, 点击提交分别向不同的地址提交数据...

    今天一个朋友叫帮做一个tab切换, 每一个tab内容区域都是从后台取出的数据, 这些数据要用表格的形式显示处理, 并且表格的内容区域可以修改, 如下所示: 例子查看请演示查看. 截图如图所示: 实现步 ...

  2. bootstrap tabale 点击_jquery+bootstrap实现tab切换, 每次切换时都请求数据, 点击提交分别向不同的地址提交数据...

    今天一个朋友叫帮做一个tab切换, 每一个tab内容区域都是从后台取出的数据, 这些数据要用表格的形式显示处理, 并且表格的内容区域可以修改, 如下所示: 例子查看请演示查看. 截图如图所示: 实现步 ...

  3. GitHub 代码托管平台提交代码时 emoji 表情的使用

      日语:絵文字/えもじ emoji,是日本在无线通信中所使用的视觉情感符号,绘指图画,文字指的则是字符,可用来代表多种表情,如笑脸表示笑.蛋糕表示食物等.emoji 频繁地出现在我们的聊天记录.朋友 ...

  4. 检查压缩包是否损坏_修复损坏的gzip压缩文件之原理篇

    接修复损坏的gzip压缩文件之原理篇,再次引用GZIP结构图: 已知修复一个损坏的gzip文件的关键环节在于找到下一个正常压缩包的起始点.根据结构图中的信息可知,每个压缩包的开始结构中有是否到达尾部标 ...

  5. 当一个软件新版本提交测试时要有,如何改善没完没了的软件测试版本?

    51Testing软件测试网1B5~A[-B+FfZg 开发人员3天出1个新的软件版本?1天1个新的版本?甚至1天3个版本?人员不得不每天不停地更换软件版本,而这种情况会导致一些不利的后果:\L ^S ...

  6. Git 提交代码时添加 emoji 图标

    文章目录 Git 提交代码时添加 emoji 图标 在commit时添加一个emoji表情图标 添加多个emoji表情图标 Git 提交代码时添加 emoji 图标 使用git的开发者都知道提交代码的 ...

  7. 在可编辑表格EditorGrid中,我选择一行已输入的数据,点击删除按钮,该行数据将被删除,然后当我点击表单提交按钮时,已经被删除的那一行数据仍然被插入数据库中...

    为什么80%的码农都做不了架构师?>>>    问题描述:在可编辑表格中,我选择一行已输入的数据,点击删除按钮,该行数据将被删除,然后当我点击表单提交按钮时,已经被删除的那一行数据仍 ...

  8. 在showModalDialog和showModelessDialog中提交form时不弹出新窗口

    在showModalDialog和showModelessDialog中提交form时不弹出新窗口 方法一: 在弹出的页面head部分加上<base target="_self&quo ...

  9. IntelliJ IDEA 提交代码时出现:Code analysis failed with exception: com.intellij.psi......(亲测)

    阅读目录: IntelliJ IDEA 提交代码时出现:Code analysis failed with exception: com.intellij.psi...... 错误原因: 错误展示: ...

最新文章

  1. 启动项目时出现java.io.EOFException异常。
  2. python培训出来的有公司要吗-Python培训班出来好找工作吗?
  3. asp:HyperLink vs asp:LinkButton
  4. ALV 简单实现HTML抬头的方法 (介绍 二)
  5. 制作计算器窗口java_Java实现的窗口计算器
  6. grunt之filerev、usemin
  7. Linux网络模块全局变量,()不是Linux系统的特色.
  8. 接口报Provisional headers are shown原因和解决方法
  9. OpenCV实战4: HOG+SVM实现行人检测
  10. Redux 主要知识学习总结
  11. SpringMVC-Restful
  12. 多头注意力比单头好在哪?
  13. 条件语句与循环语句:将数字一二三四五六七八九十转化成汉字大写的壹, 贰,叁,肆,伍,陆,柒,捌,玖,拾
  14. 考研英语阅读12种解题技巧!码住!
  15. Sublime Text的使用代码块安装的模块
  16. 数据模型建设-维度建模详解
  17. 数字孪生医院的智能化运营平台建设内容
  18. 写代码时尽量少用复制粘贴(ctrl+c, ctrl+v)
  19. 西门子200smart模拟量滤波防抖PLC程序,能实现电流电压和热电阻模拟量信号的采集
  20. 同指数幂相减公式_同底指数加减运算法则

热门文章

  1. windows批处理运行java程序
  2. Altium AD20更改原理图的连接节点颜色和连线颜色(结点颜色)
  3. shell类型、添加PATH环境变量、.bashrc、.profile、/etc/profile、/etc/environment
  4. 【扯皮】李诞 ▪《笑场》
  5. finally块的return语句会覆盖其他语句的return
  6. Python 常用命令
  7. MUI开发指南(二) webview对象
  8. click和blur冲突的问题
  9. javaweb之mysql数据库
  10. Java——动态绑定和多态