How to get the last commit date for a bunch of files in Git?

Git

Git Problem Overview


What's the simplest one-liner to get the last commit date for a bunch of files in a Git repository (i.e., for each file, the date of the last commit that changed that file)?

The context for this is that I'm using other Bash commands to find a long list of files matching some criteria, and I'd like to just pipe this list into a Git command to get the last commit date for each file.

Git Solutions


Solution 1 - Git

The following command will be helpful:

git log -1 --format=%cd filename.txt

This will print the latest change date for one file. The -1 shows one log entry (the most recent), and --format=%cd shows the commit date. See the documentation for git-log for a full description of the options.

You should be able to easily extend this for a group of files.

Solution 2 - Git

Slightly extending Greg's answer, git log can take multiple paths in its argument. It will then show only the commits which included those paths. Therefore, to get the latest commit for a group of files:

git log -1 --format=%cd -- fileA.txt fileB.txt fileC.txt

I'm pretty rubbish at shell scripting, so I'm not exactly sure how to construct that command via piping, but maybe that'd be a good topic for another question.

Solution 3 - Git

Use git ls-files to find git files, and then git log to format the output. But since git log will group several file together when they share same commit time, I prefer to have it process one file at a time and then sort the result.

The resulted one-liner:

for f in $(git ls-files); do git --no-pager log --color -1 --date=short --pretty=format:'%C(cyan)%ai%Creset' -- $f ; echo  " $f"; done |sort -r

If you want to add it to your .bashrc:

function gls() {
    for f in $(git ls-files); do git --no-pager log --color -1 --date=short --pretty=format:'%C(cyan)%ai%Creset' -- $f ; echo  " $f"; done |sort -r
}

Then running gls will output something like:

2019-09-30 11:42:40 -0400 a.c
2019-08-20 11:59:56 -0400 b.conf
2019-08-19 16:18:00 -0400 c.c
2019-08-19 16:17:51 -0400 d.pc

The result is in time descending order.

Solution 4 - Git

Here's a one liner using find (broken into several for readability, but thanks to the trailing backslashes, copy–paste should work):

find <dirs...> -name '<pattern>' <any other predicate to get what you want> \
  -exec git log -1 --format="AAA%ai NNN" '{}' \; \
  -exec echo '{}' XXX \; \
| tr \\n N | sed -e 's/AAA/\n/g' | sed -e 's/NNNN/ /g' -e 's/XXX.*//g'

The overly complex newline mangling with tr and sed is just there to get date and filename on one line, and to ignore untracked files. You have to make sure that none of your files contain those silly markers AAA XXX NNNN.

Solution 5 - Git

To get the last commit date in a long(Unix epoch timestamp) format in git(for any file) use the following command.

  • Command: git log -1 --format=%ct filename.txt
  • Result: 1605094689

Note:

  1. You can specify any file along with an extension in the git project.
  2. You can visit the git-log documentation to get a more detailed description of the options.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjonderryView Question on Stackoverflow
Solution 1 - GitGreg HewgillView Answer on Stackoverflow
Solution 2 - GitnickfView Answer on Stackoverflow
Solution 3 - GitPenghe GengView Answer on Stackoverflow
Solution 4 - GitdiemoView Answer on Stackoverflow
Solution 5 - GitKeshav LodhiView Answer on Stackoverflow