近日,苹果公司新发布的 iOS 7.0.6 一度闹得沸沸扬扬,这是由于它修复了一个因goto 而引起的bug 。对于广大开发者来说,这个bug 出现的原因以及如何避免其出现,成了热议的话题。
知名博主陈皓分享了他对于该事件的思考。他认为这可能是代码在合并过程中导致的bug,而这种bug 却很难在代码审查时被发现。
前微软工程师,现就职于 Github 的 Phil Haack 在其博客中分享了他的团队是如何审查合并提交的。在此前,他们的合并流程是这样的(假设要将 master 分支合并到 long-running-branch 分支上):
- 在 long-running-branch 分支上创建一个新的分支:merge-master-into-long-running-branch。
- 在该分支上执行合并。
- 将该分支推送(push)到 Github 上。
- 根据该提交创建一个拉请求(pull request),请团队其他人进行审查。
在 git 中,这相当于执行下面的命令集:
git checkout long-running-branch git checkout -b merge-master-into-long-running-branch git merge master # Manually do a lot of work to resolve the conflicts and commit those changes git push origin merge-master-into-long-running-branch
然而这样的方式可能会产生问题。Phil 的同事 Paul Betts 指出,在将一个分支合并到另一个的时候,该合并提交的 diff 将显示从最后一次合并之后的所有改变。这很可能是已经审查过的代码。而我们真正想要看到的,是这次提交是否有冲突,以及如何解决这些冲突。
参与 LibGit2 开发的 Russell Belfer 给出了答案。
在将一个分支合并到另一个分支时,会在这两个分支上各创建一个合并提交。以 SignalR 的一次合并提交为例。该提交要将 release 分支合并到 dev 分支,该提交的 SHA 为 cc5b002a5140e2d60184de42554a8737981c846c,以 cc5b002a 代替。
我们可以使用 git diff 命令,从两个父分支上分别查看这个合并。例如:
git diff cc5b002a^1 cc5b002a git diff cc5b002a^2 cc5b002a
如果只想查看冲突的部分,可以使用 git show 命令:
git show --cc cc5b002a
git show 所展示的内容,要比整个合并提交的diff 少得多,因为–cc 选项可以忽略没有冲突的部分,即只显示与该提交的所有父分支都不相同的部分。这样,审阅者就可以更加专注于冲突的部分,从而降低bug 发生的概率。
Phil 在文章最后介绍了他是如何发现这样一个合并冲突的示例的。他执行了 git log --min-parents=2 -p --cc 命令,从而找出了至少有两个父分支的提交。
活动推荐:
2023年9月3-5日,「QCon全球软件开发大会·北京站」 将在北京•富力万丽酒店举办。此次大会以「启航·AIGC软件工程变革」为主题,策划了大前端融合提效、大模型应用落地、面向 AI 的存储、AIGC 浪潮下的研发效能提升、LLMOps、异构算力、微服务架构治理、业务安全技术、构建未来软件的编程语言、FinOps 等近30个精彩专题。咨询购票可联系票务经理 18514549229(微信同手机号)。
评论