如何审查合并的提交

  • 2014-03-06
  • 本文字数:978 字

    阅读完需:约 3 分钟

近日,苹果公司新发布的 iOS 7.0.6 一度闹得沸沸扬扬,这是由于它修复了一个因goto 而引起的bug 。对于广大开发者来说,这个bug 出现的原因以及如何避免其出现,成了热议的话题。

知名博主陈皓分享了他对于该事件的思考。他认为这可能是代码在合并过程中导致的bug,而这种bug 却很难在代码审查时被发现。

前微软工程师,现就职于 Github Phil Haack 在其博客中分享了他的团队是如何审查合并提交的。在此前,他们的合并流程是这样的(假设要将 master 分支合并到 long-running-branch 分支上):

  1. 在 long-running-branch 分支上创建一个新的分支:merge-master-into-long-running-branch。
  2. 在该分支上执行合并。
  3. 将该分支推送(push)到 Github 上。
  4. 根据该提交创建一个拉请求(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 命令,从而找出了至少有两个父分支的提交。