5

GitHub Pull Request Diff中的诡异行为

 2 years ago
source link: https://nyan.im/p/github-pull-request-diff-weird-behavior
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

GitHub Pull Request Diff中的诡异行为

Frank

January 30, 2022

去年我负责开发了产品中的一个大型feature,这个feature被分解成了A, B两个小feature。大致的工作流程是这样的:

我从master branch out出分支feature-a,在分支feature-a上开发;然后从feature-a branch out出feature-b,在feature-b上开发;最后创建feature-b -> feature-afeature-a -> master 两个PR分别进行code review并依次合并进master。

当我在开发feature-b时由于master上有了很多更新,于是我将master分别merge进了feature-afeature-b。整个流程的简化版大致如下:

当我创建从feature-bfeature-a的PR时,奇怪的问题出现了:PR的diff中混入了大量已经在master分支上的提交。虽然我相信这个问题并不会真的影响合并,但是PR中混入了很多无关的commit则会让PR难以review。

Manager告诉我我不应该直接将master分支merge进feature-b,而是应该先将master merge到feature-a,然后将feature-a merge进feature-b,也就是这样:

我照做之后问题解决了,但是这并没有解答我的疑惑:我在本地使用git diff显示出的结果是不包含master上的那些无关commit的,为什么GitHub PR的diff会和本地的diff显示不同的结果?

于是我试着基于上图的简化版模型重现了整个过程:https://github.com/frankgx97/git-diff

在从feature-bfeature-a的PR中(https://github.com/frankgx97/git-diff/pull/2/files)我们可以发现:图中 -A, +AE 的两行是在master上的commit E中的更改,因为feature-afeature-b上均已经存在commit E,所以这个更改不应该显示在这里。

通过查找一些资料发现,GitHub PR的diff默认提供的是三点diff,而git diff默认则是两点diff。两者的区别在于三点diff是用来比较A和B的公共祖先与B的差异,git diff a...b等价于 git diff $(git merge-base a b) b

然而git cli的三点diff并没有包含 -A, +AE ,这似乎并不能用三点diff来解释。

$ git diff feature-a...feature-b
 AE
 B
+C
+D

通过git merge-base命令可以发现,git cli认为feature-afeature-b的merge base是f4c1318,也就是图中的commit E。也就是说git cli的三点diff是在比较commit E和D,这符合我们上面得到的结果。

$ git merge-base feature-a feature-b
f4c13184f9af7f2dcd0fe706a355f7703e7bc39d

不过从GitHub中的diff来看,被比较的应该是topic branch的最新commit D(85c13ed)和feature-a和feature-b的公共祖先B(01c9a49)。我猜测GitHub并不是直接使用的git中的三点diff,而是选取两个分支的公共祖先与topic branch最新的commit进行比较而得出的diff。

$ git diff 01c9a49 85c13ed
@@ -1,2 +1,4 @@
-A
+AE
 B
+C
+D

我又将git仓库上传到了GitLab和BitBucket,这两个平台上的diff均与git cli一致。

Screen%20Shot%202022-01-23%20at%2021.49.22.png!sGitLab

Screen%20Shot%202022-01-24%20at%2000.31.55.png!sBitBucket

于是就引出了下面两个问题:

  1. 为什么GitHub的diff会和cli与其他平台不同?这是刻意设计,还是bug?
  2. 这种场景下使用git的best practice是什么?

References


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK