如何检索git存储库中所有文件的最后修改日期


64

我知道如何在git存储库中检索单个文件的最后修改日期:

git log -1 --format="%ad" -- path/to/file

是否有简单有效的方法对存储库中当前存在的所有文件执行相同的操作?

Answers:


74

一个简单的答案是遍历每个文件并显示其修改时间,即:

git ls-tree -r --name-only HEAD | while read filename; do
  echo "$(git log -1 --format="%ad" -- $filename) $filename"
done

这将产生如下输出:

Fri Dec 23 19:01:01 2011 +0000 Config
Fri Dec 23 19:01:01 2011 +0000 Makefile

显然,您可以控制它,因为此时它只是一个bash脚本-因此,请随时根据自己的内心需求进行自定义!


2
我希望有一个选项可以在单次git log中获得组合的输出,但是您的答案比我想使用find的答案要好。我不知道git-ls-tree,它的优点是仅列出存储在存储库中的文件,跳过.git文件夹并忽略了文件。谢谢。
埃里克·布雷基米尔(EricBréchemier)2012年

没问题,埃里克;您将遵循与我相同的方法-即查找并忽略.git目录!:)使用git plumbing命令可能有一些选项,但是坦率地说,这很好用。如果您可以找到某种方式一次获取每个文件的信息,那将是最好的方法-但是请记住,git在提交状态而不是单个文件状态下运行。
2012年

11
如果您想要可排序的时间戳而不是人类可读的日期,则建议使用--format =“%ai”。
ThorSummoner 2014年

2
由于“HEAD”只是一个参考,你可以使用任何你想要的参考,无论是标签,分支,提交哈希等。
安德鲁M.

1
如@ThorSummoner所说,使用%ai格式表示日期,然后用管道将结果排序:git ls-tree -r --name-only HEAD | while read filename; do echo "$(git log -1 --format="%ai" -- $filename) $filename"; done | sort
John Hunt

21

这种方法也适用于包含空格的文件名:

git ls-files -z | xargs -0 -n1 -I{} -- git log -1 --format="%ai {}" {}

输出示例:

2015-11-03 10:51:16 -0500 .gitignore
2016-03-30 11:50:05 -0400 .htaccess
2015-02-18 12:20:26 -0500 .travis.yml
2016-04-29 09:19:24 +0800 2016-01-13-Atlanta.md
2016-04-29 09:29:10 +0800 2016-03-03-Elmherst.md
2016-04-29 09:41:20 +0800 2016-03-03-Milford.md
2016-04-29 08:15:19 +0800 2016-03-06-Clayton.md
2016-04-29 01:20:01 +0800 2016-03-14-Richmond.md
2016-04-29 09:49:06 +0800 3/8/2016-Clayton.md
2015-08-26 16:19:56 -0400 404.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-bradycardia-algorithm.htm
2015-12-23 17:03:51 -0500 _algorithms/acls-pulseless-arrest-algorithm-asystole.htm
2016-04-11 15:00:42 -0400 _algorithms/acls-pulseless-arrest-algorithm-pea.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-secondary-survey.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-suspected-stroke-algorithm.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-tachycardia-algorithm-stable.htm
...

最后,可以通过修改时间戳对输出进行排序| sort

git ls-files -z | xargs -0 -n1 -I{} -- git log -1 --format="%ai {}" {} | sort

有什么办法让它按修改时间戳排序?
阿梅里奥·瓦兹克斯·雷纳

1
@ AmelioVazquez-Reina:只需添加`| | 排序到命令末尾。
dotancohen

2
这工作,但需要花费过长...时间... ...
Guillochon

5

这是安德鲁·M。答案的一个小调整。(我无法评论他的回答。)

将第一个$ filename括在双引号中,以支持带有嵌入式空格的文件名。

git ls-tree -r --name-only HEAD | while read filename; do
    echo "$(git log -1 --format="%ad" -- "$filename") $filename"
done

样本输出:

Tue Jun 21 11:38:43 2016 -0600 subdir/this is a filename with spaces.txt

我赞赏Andrew的解决方案(基于ls-tree)适用于裸仓库!(这不适用于使用ls文件的解决方案。)


您还可以跳过回显:git log -1 --format =“%ad $ filename”
Kevin Lyda

0

这是安德鲁·M(Andrew M)答案的鱼壳版本,适用于使用鱼的人。

git ls-tree -r --name-only HEAD | while read -l filename
    printf '%s %s\n' (git log -1 --format="%ai" -- $filename) $filename
end

我将其存储为钓鱼功能,以方便使用。


0

对于使用Windows和PowerShell的我们这些人,Andrew M的答案以及对计算机可读的调整:

git ls-tree -r --name-only HEAD | ForEach-Object { "$(git log -1 --format="%ai" -- "$_")`t$_" }

输出示例:

2019-05-07 12:00:37 -0500   .editorconfig
2016-07-13 14:03:49 -0500   .gitattributes
2019-05-07 12:00:37 -0500   .gitignore
2018-02-03 22:01:17 -0600   .mailmap
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.