为什么使用git blame --ignore-rev/--ignore-revs-file命令无效?

13

git blame --ignore-revs-file显然是现代Git中存在的一个选项。

只有一个问题,它并不起作用。

或者,至少对我来说不起作用:

您可以将此添加到shell脚本中:

mkdir -p /tmp/blarp
cd /tmp/blarp
git init
cat << EOF > file.txt
one
two
three
EOF
git add file.txt
git commit --author "One <one@example.com>" -m 'one commit'
cat << EOF > file.txt
one
awesome
three
EOF
git add file.txt
git commit --author "Two <two@example.com>" -m 'two commits'
cat << EOF > file.txt
one
awesome
sauce
EOF
git add file.txt
git commit --author "One <one@example.com>" -m 'three commits'
git rev-parse HEAD~1 > ignore.txt
git blame --ignore-revs-file=ignore.txt file.txt

对我来说,这表明:

^b6d40d5 (One 2019-12-30 21:47:15 +0000 1) one
1c185c4c (Two 2019-12-30 21:47:15 +0000 2) awesome
d8b9bafd (One 2019-12-30 21:47:15 +0000 3) sauce

但我希望看到

^b6d40d5 (One 2019-12-30 21:47:15 +0000 1) one
^b6d40d5 (One 2019-12-30 21:47:15 +0000 2) two
d8b9bafd (One 2019-12-30 21:47:15 +0000 3) sauce

或者
^b6d40d5 (One 2019-12-30 21:47:15 +0000 1) one
d8b9bafd (One 2019-12-30 21:47:15 +0000 2) awesome
d8b9bafd (One 2019-12-30 21:47:15 +0000 3) sauce

但事实并非如此。我发现如果更改只是空格的更改,它们将被忽略......但git文档对此并不明确,只是建议使用以下命令:

--ignore-revs-file

忽略在文件中列出的修订版本,该文件必须与fsck.skipList的格式相同。可以重复使用此选项,并且这些文件将在使用blame.ignoreRevsFile配置选项指定的任何文件之后被处理。空文件名“”将清除先前处理的文件中版本列表。

有什么线索说明为什么git blame --ignore-revs-file=revs-to-ignore 对我来说似乎不能正确工作吗?


1
这是一个好问题 - 我已经能够重现这个效果,并尝试打开 blame.markUnblamablesblame.markIgnoredLines 设置,但似乎在这里它们也无法起作用。这似乎不对,但新的归咎/分配算法充满了启发式方法,描述也不太清楚,所以也许是有意为之,或者可能是一个错误。 - torek
你使用的是哪个版本的git? - Daniel
2.24.0 - 和其他版本 - Wayne Werner
仍然在 macOS 的 git 2.28.0 中看到这个问题。 - Devin Rhode
有人真的能够使这个工作吗? - Jesse
1
也许这是有意为之的,或者可能是一个错误。这是有意为之的。ignore-rev旨在忽略不感兴趣的提交。完全改变一行的内容是有趣的 :) 我同意在文档中应该更清楚地传达这个意图。 - Michael Platings
2个回答

4

请检查 Git 2.29 (Q4 2020) 是否已经修复了该问题:"git blame --ignore-rev/--ignore-revs-file"(man) 未能验证其输入是否是有效的修订版本,并且未考虑用户可能想要提供带注释的标签而不是提交,这一问题已得到纠正。

请查看提交 610e2b9提交 f58931c(2020年9月24日)由Junio C Hamano (gitster完成。
(由Junio C Hamano -- gitster --合并于提交 230ff3e,2020年10月4日)

blame: 验证并剥离忽略列表中的对象名称

该命令从命令行或文件中读取要放入忽略列表中的对象名称列表,但不检查它们的对象类型(从文件中读取的对象甚至未检查其对象是否存在)。

扩展 oidset_parse_file() API,并允许它接受回调函数,用于在读取不适当的输入时终止程序(例如),或修改读取的对象名称(例如,当读取指向提交的标签时,调用方想要一个提交对象名称),并在处理忽略列表的代码中使用它。


在 Git 2.30 (2021年第一季度) 中, "git blame --ignore-revs-file=<file>(man)" 学会了忽略输入中不存在的对象名称,而不是抱怨。

请查看 提交 c714d05(2020年11月10日)由René Scharfe (rscharfe)进行。
(由Junio C Hamano -- gitster --提交 b4e245a中合并,2020年11月18日)

blame:静默忽略无效的 ignore 文件对象

报告者:Jean-Yves Avenard
署名者:René Scharfe
评审者:Barret Rhoden

自从 610e2b9240("blame: validate and peel the object names on the ignore list",2020-09-24,Git v2.29.0-rc0 -- merge 列在 batch #19 中)git blame(man) 报告检查使用 --ignore-rev 指定的对象以及使用 --ignore-revs-file 和配置选项 blame.ignoreRevsFile 加载的文件是否为实际对象,如果不是,则失败。目的是向用户报告拼写错误。 这也破坏了使用单个忽略文件来忽略多个存储库的能力。 文件中的拼写错误可能比命令行上少,因此在此处提醒的用处较小。 通过跳过非提交内容而不死亡来恢复该功能。

2
TL;DR: ignore-revs特性是为了重构提交而设计的,不适用于完全更改行的提交。
嗨 Wayne,
感谢你的尝试。很抱歉你第一次使用它的体验不好。我认为文档可以改进,以更好地传达该功能的意图。
git blame --ignore-rev试图找到与“awesome”有些相似的行。但是“awesome”和“two”没有任何共同之处,因此它放弃了,并将“awesome”归因于实际添加它的提交。
有一个特性可以识别这种情况,但需要显式启用:
如果设置了blame.markUnblamableLines配置选项,则那些被忽略的提交触及的无法归因于另一个修订版本的行将标记为*。
使用此选项,对于您的示例脚本,我看到一个*表示问题:
^6bce3bb (One 2021-03-28 15:08:08 +0100 1) one
*b75aaf2 (Two 2021-03-28 15:08:08 +0100 2) awesome
5d3b18c7 (One 2021-03-28 15:08:08 +0100 3) sauce

如果您尝试在真正想要忽略的提交上运行git blame --ignore-rev(例如重新格式化您的代码),那么它应该能够正常工作。
例如,如果我更改您的脚本以将two替换为awesome TWO,则会看到以下内容:
^5307c74 (One 2021-03-28 15:14:52 +0100 1) one
^5307c74 (One 2021-03-28 15:14:52 +0100 2) awesome TWO
9d3fcc01 (One 2021-03-28 15:14:52 +0100 3) sauce

什么原因会导致某行代码不再归属于之前的提交?在我的代码库中,我发现一些被忽略的提交所修改的代码行被正确地归属于之前的提交,而其他一些则没有(如果我设置了 markUnblamableLines,那么我会看到被忽略的 SHA 和一个 * 来表示这一点)。 - Adam Parkin
1
@AdamParkin 如果算法无法识别附近的相似行,则它将是“无可指责的”。但是该算法并不简单,因此可能还有更多内容。如果您认为有可以更好处理的示例,我很乐意查看。 - Michael Platings
我没有具体的例子可以分享,但我在工作中看到了一个 Python 项目的示例,其中 Black 重新格式化了一行长表达式(例如:some_variable = some_func(with, a, lot, of, parameters, that, got, really, really, really, long)),使其以单个闭合括号结束,这导致 blame ignore 无法找到之前的提交而失败。 - Adam Parkin
我尝试过了,但无法重现这个问题。如果你找到了复现方法,请告诉我,我会看看能否改进。谢谢。 - Michael Platings

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接