Git:重命名后可靠地获取责备历史

问题描述

我正在尝试构建一个 git log 命令来检索具有以下属性文件历史记录(在复制和重命名之后):

  1. 我希望日志在注释后“关闭”——也就是说,如果我 git blame -elfwM 文件在历史记录中的任何提交(使用当时文件的任何名称),我希望注释中出现的每个提交也包含在历史记录中。

  2. 我想知道历史记录中每个条目的文件原始名称。对于没有重命名文件的提交,这将与文件名相同;对于提交的提交,我想知道该提交的每个父级中的原始文件名。

  3. 对于文件的任何给定注释(在其历史记录中的任何点),我希望该提交的相应历史记录条目(我们知道存在于属性 1)使其作者、日期和文件名匹配注释的作者、日期和文件名。

  4. 满足 (1),我想要尽可能少的额外提交。我特别想排除对文件没有任何影响的提交。

到目前为止,我能做的最好的是:git log --raw --follow -m --pretty="%H%n%P%n%aL%n%cs%n%s" -- FILENAME。这是我在这条线背后的想法:

  • --follow 应该完成以下重命名和复制的工作(但不给我文件名)
  • --pretty=... 应该给我提交、父母、作者、提交日期和主题。我猜原作者 + 提交日期是 git blame 使用的,但如果这是错误的,请纠正我。
  • --raw 应该为我提供给定提交的原始文件名和新文件名。
  • -m 应该为合并提交拆分条目,以便我可以获得单个父项的原始名称

这在典型情况下似乎没问题,但我写了一个 script 来演示失败的场景。以下是其中一次运行的示例输出

Created git repository at /var/folders/y4/2t2n3dhj4bz4cwsrm801t_bm0000gn/T/tmp.Rtj55RWb
Committed: cbc8198fd5eb975ab5fc1fcc66889872429a40fe (master) Initial commit
Committed: 5628acbb478a8786eaec186bf4e6050142049848 (workbench) Renamed foo.txt to bar.txt
Committed: 2f6d49b3aa35ffa2953a65e21ba5c21d130fa3b1 (workbench) Modified line 3 of bar.txt.
Committed: bac0a739a1fd2acc7c0ce466d9055942cbf87ccb (workbench) Added dummy.txt
Committed: c018ca1b4436b73237c9a727ed2353cbd8152928 (workbench) Removed dummy.txt
Committed: 18bec91206357ec23ffe53a01d20ec64f7667e4e (master) Renamed foo.txt to baz.txt
Committed: a724f0cc49f39d9e99b8794b9f263efb5bc51da1 (master) Modified line 8 of baz.txt.
Committed: 4628679d5695c9a5fb080124b854f336fdf683d1 (master) Added dummy.txt
Committed: 58f700c48a16496dfd540126dab5e55952847993 (master) Removed dummy.txt
Committed: 633056c27cf0e3afb9529d478cf51ed0bdaa918e (master) Merged bar.txt and baz.txt as foo-merged.txt
----------------------------------------
633056c27cf0e3afb9529d478cf51ed0bdaa918e
58f700c48a16496dfd540126dab5e55952847993 c018ca1b4436b73237c9a727ed2353cbd8152928
john.doe
2021-04-10
Merged bar.txt and baz.txt as foo-merged.txt
:100644 100644 27393f0 bb5a6e5 R089     baz.txt foo-merged.txt

a724f0cc49f39d9e99b8794b9f263efb5bc51da1
18bec91206357ec23ffe53a01d20ec64f7667e4e
john.doe
2021-04-10
Modified line 8 of baz.txt.
:100644 100644 4f9956e 27393f0 M        baz.txt

18bec91206357ec23ffe53a01d20ec64f7667e4e
cbc8198fd5eb975ab5fc1fcc66889872429a40fe
john.doe
2021-04-10
Renamed foo.txt to baz.txt
:100644 100644 4f9956e 4f9956e R100     foo.txt baz.txt

5628acbb478a8786eaec186bf4e6050142049848
cbc8198fd5eb975ab5fc1fcc66889872429a40fe
john.doe
2021-04-10
Renamed foo.txt to bar.txt
:100644 000000 4f9956e 0000000 D        foo.txt

cbc8198fd5eb975ab5fc1fcc66889872429a40fe

john.doe
2021-04-10
Initial commit
:000000 100644 0000000 4f9956e A        foo.txt
----------------------------------------
cbc8198fd5eb975ab5fc1fcc66889872429a40fe foo.txt (<john.doe@gmail.com> 2021-04-10  1) This is line 1
cbc8198fd5eb975ab5fc1fcc66889872429a40fe foo.txt (<john.doe@gmail.com> 2021-04-10  2) This is line 2
2f6d49b3aa35ffa2953a65e21ba5c21d130fa3b1 bar.txt (<john.doe@gmail.com> 2021-04-10  3) Modified bar
cbc8198fd5eb975ab5fc1fcc66889872429a40fe foo.txt (<john.doe@gmail.com> 2021-04-10  4) This is line 4
cbc8198fd5eb975ab5fc1fcc66889872429a40fe foo.txt (<john.doe@gmail.com> 2021-04-10  5) This is line 5
cbc8198fd5eb975ab5fc1fcc66889872429a40fe foo.txt (<john.doe@gmail.com> 2021-04-10  6) This is line 6
cbc8198fd5eb975ab5fc1fcc66889872429a40fe foo.txt (<john.doe@gmail.com> 2021-04-10  7) This is line 7
a724f0cc49f39d9e99b8794b9f263efb5bc51da1 baz.txt (<john.doe@gmail.com> 2021-04-10  8) Modified baz
cbc8198fd5eb975ab5fc1fcc66889872429a40fe foo.txt (<john.doe@gmail.com> 2021-04-10  9) This is line 9
cbc8198fd5eb975ab5fc1fcc66889872429a40fe foo.txt (<john.doe@gmail.com> 2021-04-10 10) This is line 10

第三行显示 bar.txt 在 2f6d49b3aa35ffa2953a65e21ba5c21d130fa3b1 中被修改。不幸的是,这个提交没有出现在历史记录中 - 我原以为它会因为 --follow 而出现,而且我还预计 633056c27cf0e3afb9529d478cf51ed0bdaa918e 由于 -m 出现第二个条目,因为它有两个父项(我原以为该条目会有像 :100644 100644 27393f0 bb5a6e5 R089 bar.txt foo-merged.txt 这样的原始行)。

注意:如果可以获取此信息,但不能在单个 git log 命令中获取,则使用恒定数量命令的解决方案也可以使用。我想避免执行诸如递归检查注释以获取历史记录之类的事情,如果提交的每一行都发生了更改,例如由于重新格式化,该特定策略也会失败。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)