113

I know how to retrieve the last modification date of a single file in a Git repository:

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

Is there a simple and efficient way to do the same for all the files currently present in the repository?

  • 1
    It's 2022, ten years after this question was asked. Still no solution to make such simple tasks (in this case akin to ls -l) easier to type and to remember? Yes I know I could save the script in an executable, but that works only until I go on a different machine, which usually is when I need the feature the most! – Davide Aug 30 '22 at 11:24
  • for large repos, i have started git-file-times – milahu Jul 15 '26 at 19:59

7 Answers7

114

A simple answer would be to iterate through each file and display its modification time, i.e.:

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

This will yield output like so:

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

Obviously, you can control this since its just a bash script at this point--so feel free to customize to your heart's content!

Andrew M.
  • 11,450
  • 3
    I was hoping that there was an option to get a combined output in a single run of git log, but your answer is better than the one I had in mind using find. I did not know git-ls-tree, which has the advantage of listing only the files stored in the repository, skipping the .git folder and ignored files. Thanks. –  Jun 23 '12 at 08:25
  • No problem, Eric; you are following the same route that I did--i.e., doing a find and ignoring the .git directory! :) There may be some options using the git plumbing commands, but quite frankly, this works pretty well. If you could find some way to get the information on a per file basis all at once, that would work best--but remember, git operates on the state of commits, not the state of individual files. – Andrew M. Jun 25 '12 at 16:40
  • Can this be adapted to work on a commit other than the current checkout HEAD? I think the log command is working relative to the HEAD here by default. – ThorSummoner May 30 '14 at 19:30
  • 15
    I recommend using the --format="%ai" if you want sortable time stamps instead of human readable dates. – ThorSummoner May 30 '14 at 19:45
  • 2
    Since "HEAD" is just a reference, you can use any reference you want, be it a tag, branch, commit hash, etc.. – Andrew M. May 30 '14 at 23:29
  • 3
    as @ThorSummoner said, use %ai format for date, and then just pipe to sort to sort the results: git ls-tree -r --name-only HEAD | while read filename; do echo "$(git log -1 --format="%ai" -- $filename) $filename"; done | sort – John Hunt Aug 18 '17 at 08:50
  • Is this still the best way to proceed in 2022? It's annoying as such simple tasks (in this case akin to ls -l) becomes such a huge pita that one has to script... – Davide Aug 30 '22 at 11:15
46

This approach also works with filenames that contain spaces:

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

Example output:

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
...

The output can be sorted by modification timestamp by adding | sort to the end:

git ls-files -z | xargs -0 -n1 -I{} -- git log -1 --format="%ai {}" {} | sort
dotancohen
  • 2,728
William Entriken
  • 632
  • 6
  • 13
  • Any way to get this sorted by modification timestamp? – Amelio Vazquez-Reina Jun 21 '16 at 18:16
  • 1
    @AmelioVazquez-Reina: Just add | sort to the end of the command. – dotancohen Oct 18 '17 at 19:24
  • 6
    This works but takes a loooong time... – Guillochon Jan 24 '18 at 15:18
  • this counts file renames as file modifications. to not count file renames as file modifications, replace git log -1 with git log --follow --diff-filter=ACM -1 with ACM = add copy modify. 2) maybe replace %ai with %ci, because the committer date can be more up-to-date than the author date. 3) for sorting, better use the integer timestamps %at or %ct with sort -n -k1, because this also works with different timezones
  • – milahu Jun 17 '26 at 18:06