Git怪-L bug?

Git blame -L bug?

我 运行 git blame -L 有多个 -L 选项,以便在单个 git 调用中获取非连续行的行信息。

我相信这个电话:

git blame -L38,38 -L40,40 <file>

应该等同于这两个单独调用

git blame -L38,38 <file>
git blame -L40,40 <file>

但是,我 运行 在一个案例中使用多个 -L 选项实际上返回了第 38 和 39 行,而不是预期的第 38 和 40 行:

$ git blame -L38,38 -L40,40 <file>
b6543ffe (Some Body 2015-11-24 15:15:03 -0500 38)           SOME CODE
b6543ffe (Some Body 2015-11-24 15:15:03 -0500 39)           SOME OTHER CODE

当我只有一个 -L40,40 时 git 实际上 returns 第 40 行正确:

$ git blame -L40,40 <file>
b6543ffe259 (Some Body 2015-11-24 15:15:03 -0500 40)                SOME CODE

关于 -L 的实际工作原理,我是否遗漏了什么或者这是一个 git 错误?

我尝试同时使用 git 版本 2.7.0.windows.1 和 2.11.0.windows.1.

应该(你可以看到how it was implemented in this patch series in 2013

但显然不是(可能是错误)。
这导致了一些项目,例如 isaacbernat/pycrastinate to Fix for git blame multiple line ranges

This fix calls git blame for each line separately.


2020 年 8 月更新

在 Git 2.29(2020 年第 4 季度)之前,当给定多个目标线范围时,“git blame -La,b -Lc,d(man)”过于急于合并原始线组和显示不正确的结果,已更正。

参见 commit c2ebaa2, commit dd7c611, commit 6dbf0c7 (13 Aug 2020) by Jeff King (peff)
(由 Junio C Hamano -- gitster -- in commit 93121df 合并,2020 年 8 月 19 日)

blame: only coalesce lines that are adjacent in result

Reported-by: Nuthan Munaiah
Signed-off-by: Jeff King

After blame has finished but before we produce any output, we coalesce groups of lines that were adjacent in the original suspect (which may have been split apart by lines in intermediate commits which went away).

However, this can cause incorrect output if the lines are not also adjacent in the result.
For instance, the case in t8003 has:

ABC
DEF  

which becomes

ABC
SPLIT
DEF  

Blaming only lines 1 and 3 in the result yields two blame groups (one for each line) that were adjacent in the original.
That's enough for us to coalesce them into a single group, but that loses information: our output routines assume they're adjacent in the result as well, and we output:

<oid> 1) ABC
<oid> 2) SPLIT  

This is nonsense for two reasons:

  • we were asked about line 3, not line 2; we should not output the SPLIT line at all
  • commit <oid> did not touch the SPLIT line at all!
    We found the correct blame for line 3, but the bug is actually in the output stage, which is showing the wrong line number and content from the final file.

We can fix this by only coalescing when both the suspect and result lines are adjacent. That fixes this bug, but keeps coalescing in cases where want it (e.g., the existing test in t8003 where SPLIT goes away, and the lines really are adjacent in the result).