我正在尝试构建一个git log
命令来检索具有以下属性的文件的历史记录(跟随副本和重命名):
我希望日志在注释之后“关闭”——也就是说,如果我
git blame -elfwM
在历史记录中提交任何提交(使用当时文件的任何名称),我希望注释中出现的每个提交也被载入史册。我想知道历史记录中每个条目的文件原始名称。对于未重命名文件的提交,这将与文件名相同;对于这样做的提交,我想知道该提交的每个父级中的原始文件名。
对于文件的任何给定注释(在其历史记录中的任何时间点),我希望该提交的相应历史记录条目(我们知道从属性 1 中存在)使其作者、日期和文件名与作者、日期和文件名匹配注释的文件名。
满足(1),我希望尽可能少的额外提交。我特别想排除不会以任何方式影响文件的提交。
到目前为止,我能做的最好的事情是:git log --raw --follow -m --pretty="%H%n%P%n%aL%n%cs%n%s" -- FILENAME
. 这是我在这条线背后的想法:
--follow
应该完成以下重命名和副本的工作(但不给我文件名)--pretty=...
应该给我提交、父母、作者、提交日期和主题。我猜原作者+提交日期是什么git blame
用途,但如果那是错误的,请纠正我。--raw
应该给我给定提交的原始文件名和新文件名。-m
应该拆分合并提交的条目,以便我可以获得单个父母的原始名称。
这在典型情况下似乎可以正常工作,但我编写了一个脚本来演示失败的场景。这是其中一次运行的示例输出:
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
命令中,使用恒定数量的命令的解决方案也可以工作。我想避免做诸如递归检查注释以得出历史记录之类的事情,并且如果存在每行都更改的提交(例如,由于重新格式化),那么该特定策略也会失败。