git log --numstat 有奇怪的数据

git log --numstat has weird data

我运行这个命令:

git log HEAD --numstat --pretty="%ae" | cat

我看到了这个:

6       4       frontend/src/Frontend.hs
aviansys@gmail.com
dan.side@gmail.com
dan.side@avian.systems

3       3       dep/rhyolite/github.json
29      14      frontend/src/Frontend.hs
aviansys@gmail.com

3       1       backend/src/Backend/RequestHandler.hs
27      18      frontend/src/Frontend.hs
dan.side@avian.systems

5       0       default.nix
7       0       dep/reflex-dom/default.nix
7       0       dep/reflex-dom/github.json
7       0       dep/reflex/default.nix
7       0       dep/reflex/github.json
dan.side@avian.systems
dan.side@avian.systems
dan.side@avian.systems

将多个电子邮件与一个提交关联到底意味着什么?这是否可能意味着该人从一个网络转移到另一个网络(比如把他们的笔记本电脑带回家,然后完成他们的提交?)我正在尝试解析提交并将它们分配给一个作者,但是将多个电子邮件附加到一个提交正在这个更难?

您确定您看到的是具有多个地址的提交吗?在我看来,您看到的提交有 no numstat-worthy 更改(例如合并)。

如果你说“%h %ae %s”而不只是“%ae”会怎样?

如您所见,您在 git log 输出中包含了合并。默认情况下,在查看合并时,git log 不会 将合并与其 parent 进行比较,因此也不会出现 --numstat 输出。

跳过合并(使用 git log --no-merges)是......好吧,但是如果你这样做,你会丢失关于合并期间所做的任何更改的信息。这可能是您能做的最好的事情,因为您可以 从合并中获得的信息很棘手。

考虑如下图:

...--o--A
         \
          M--...
         /
...--o--B

Git 将 M 与...进行比较?标准 git diff 比较 两个 提交。您应该比较哪两个提交,以了解 M 中的快照?是A-vs-M,还是B-vs-M

这个问题没有一个正确答案。为了避免必须选择答案,默认情况下 git log 根本不会打扰 M。但是您可以使用以下三个选项中的任何一个来告诉它 应该 差异:

  • -c:产生一个组合差异
  • --cc(两个破折号,两个小写字母 C):产生组合差异
  • -m:通过 "virtually splitting" 合并
  • 产生多个 non-combined 差异

这两种组合差异并不完全相同,但我从未见过对它们之间差异的意图进行适当的描述。他们都首先从差异中抛出 任何 文件,其在 M 中的副本与它在 A 或 [= 中的副本完全匹配85=] B。 (如果合并有两个以上的parents,这个阶段会丢弃任何与anyparentparent中的副本完全匹配的文件。)

然后,减少了文件数量——有时减少到零!——合并的差异继续差异两个(或所有)parent的版本提交 M 中该文件的(单个)child 版本。有关更多信息,请参阅 the git diff documentation on combined merges

-m 选项更有用,尤其是与 --first-parent 选项结合使用时。在这种情况下,Git 假装(仅出于 diff 目的)M 已被拆分为多个单独的副本:

...--o--A--M1--...

...--o--B--M2--...

现在合并已经拆分,每个副本只有一个 parent,因此 Git 实际上可以只使用 git diff A M1 并向您展示。然后它可以继续 git diff B M2 并向您展示。每个差异中使用的实际快照只是实际提交的(单个)快照M

如果将其与 --first-parent 结合使用,git log 仅遍历每个合并的 first parent,并且仅生成 first-parent 合并的差异。因此,这个 git log 不是实际的图表,而是向您展示了如果图表只是:

会是什么情况
...--o--A
         \
          M--...

您根本看不到提交 B(也没有看到它的 parent),但是您 确实 得到了描述提交 M 的差异,与提交 A 相比,因此 --numstat 适用于这种情况。