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?

up vote 61 down vote accepted

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!

  • 2
    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. – Eric Bréchemier Jun 23 '12 at 8: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
  • 10
    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

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
  • Any way to get this sorted by modification timestamp? – Amelio Vazquez-Reina Jun 21 '16 at 18:16
  • @AmelioVazquez-Reina: Just add ` | sort` to the end of the command. – dotancohen Oct 18 '17 at 19:24
  • 1
    This works but takes a loooong time... – Guillochon Jan 24 at 15:18

This is a small tweak of Andrew M.'s answer. (I was unable to comment on his answer.)

Wrap the first $filename in double quotes, in order to support filenames with embedded spaces.

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

Sample output:

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

I appreciate that Andrew's solution (based on ls-tree) works with bare repositories! (This isn't true of solutions using ls-files.)

  • You can also skip the echo: git log -1 --format="%ad $filename" – Kevin Lyda Jun 2 '17 at 11:02

Here is the fish shell version of Andrew M's answer, for those that use fish.

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

I store this as a fish function for easy access.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.