Git 合并超过 1 个提交的日志合并提交

Git log merge commits with more than 1 commit merged

我想列出去年的合并提交。所以我用这个:

git log --reverse --since=2016-01-01 --until=2016-12-31 --merges

然而,这带来了大量的合并,我想只列出那些在master分支中合并超过commit的合并。

存储库中使用的流程是the GitHub Flow

理想情况下,我希望能够列出至少合并了 N 次提交的合并。

这需要对 "have merged N commits" 的含义进行定义,因为有两个明显的定义,我认为第一个明显的定义是错误的,但我不确定第二个明显的定义是否正确。

首先,让我们注意 合并提交 ——这些是由 --merges 编辑的 select——是 的任何提交两个或更多 parents。这是 merge 的名词形式,定义在 gitglossary.

由于parent的个数很容易统计,我们可以将"a merge that merges N commits"定义为"a merge that has at least N - 1 parents"。然后所有合并将合并至少 1 个提交,而合并 2 个提交的合并将有 3 parents。请注意,3-or-more-parent 合并也称为 octopus 合并。找到这些很简单:例如 git rev-list --min-parents=3 <starting-point>。将 --mergesgit loggit rev-list 一起使用——这些大部分是相同的命令,默认输出略有不同——只是 shorthand 用于 --min-parents=2,即 select 只有合并提交的提交。

大概不是你的意思。这让我们得到了另一个明显的定义,但它远没有那么明显。

一如既往,我们需要从绘制提交图的位开始。在您 运行 git merge 的典型情况下,您有这样的东西:

...--o--*--o--o--o      <-- main
         \
          o--o----o     <-- feature

你现在 git checkout main 然后 git merge feature 如果一切顺利并且 Git 可以自己合并东西,你会得到:

...--o--*--o--o--o--M   <-- main
         \         /
          o--o----o     <-- feature

合并的提交数,在这种情况下,是三个:有三个提交在 feature 上,但不在 main 上。 (有很多提交——从 * 开始向左工作,每次提交一直回到第一次提交,可能是在 both b运行ches 之前。现在,刚刚在 feature 上的三个提交也在两个 b运行ches 上。)

但是这张图很简单。这是一个不是很复杂,但也不是那么简单的:

...--o--*--o   <-- main
         \
          \      o   <-- fix1
           \    / \
            o--o   o--o   <-- feature
                \ /
                 o   <-- fix2

不清楚要计算多少次提交。这里有六个提交在 feature 上而不在 main 上,但是其中两个有 b运行ch 名称(fix1fix2)直接指向它们,因此只有两个提交仅在 feature 上,三个提交同时在 featurefix1 上,三个提交 - 两个相同,一个不同—与 fix2 共享。我们算全部六个吗?我们数到五个吗?我们只数两个吗?

在足够复杂的图中,可能有多个合并基础。在这种情况下,git merge 默认执行 递归合并 (默认 -s 策略是 recursive),它通过合并合并基础提交来工作,相当于对结果进行临时提交,然后使用该临时提交作为合并基础进行合并。这是所有情况中最难处理的情况,因为不清楚是否将虚拟合并基础算作一次提交。

假设以上所有内容都有意义,下面是计算方法

我们得到了一个现有的合并提交 M 并要求计算它有多少次提交 "brought in"。计算它们的最简单和最简单的方法——这可能是你想要的计数,但也要考虑以上所有内容——是计算从第 2 到 P-th parents(属于 P-parent 提交 M),不包括通过第一个 parent:

git rev-list --count M^@ ^M^1

这使用 gitrevisions syntax 到 select 所有 parent 的提交 M:

Other <rev>^ Parent Shorthand Notations
Two other shorthands exist, particularly useful for merge commits, for naming a set that is formed by a commit and its parent commits.

The r1^@ notation means all parents of r1. [snip]

因此,我们要求 git rev-list 查找所有 parent 可访问的所有提交,排除可从第一个 parent 访问的所有提交。 (没有必要从第一个参数中排除第二个参数,即 M^1,因为排除第二个参数会处理它。)这是有效的,因为 M^1,第一个 [=123] M 的 =] 始终是 运行 git merge 之前 b运行ch 上的提交。因此,通过 parents 2-through-P 引入的提交以及它们尚未在 b运行ch 上的所有祖先都被计算在内时间。

(对于我的第一个图表,计数为 3,对于我的第二个图表,计数为 6。如果这些 不是 您想要的计数,您将不得不细化您的问题。)

将此 git rev-list --count 步骤放入您 运行 从 git rev-list --merges --since ... --until ... 获得的提交 ID 和 select 那些结果计数至少是您选择的那些限制。将提交哈希的最终列表提供给 git log --no-walk --stdin 以查看它们。