How do I find the most recent git commit that modified a file?

GitSearch

Git Problem Overview


I want to find the most recent commit that modified a source file.

I can use git blame to see all the dates for commits by each line, but it’s difficult to see exactly which commit was the last one to touch the file.

How can I find the last commit that touched a given file in my git repository?

Git Solutions


Solution 1 - Git

git log supports looking at the history of specific files (and directories), so you can call it like this:

git log my/file.c

If you really only want to list the one most recent commit, for example to use it in a script, use the -n 1 option:

git log -n 1 --pretty=format:%H -- my/file.c

--pretty=format:%h tells git log to show only the commit hash. The -- separater stops the file name from getting interpreted as a commit name, just in case it's ambiguous.

Solution 2 - Git

If you just want to find the most recent commit, then you don't want git-log, you want git-rev-list, which lists the commit objects changing that file, in that commit path, starting with the most recent one (chronologically). Simply put:

git rev-list -1 <commit> <filename>

For git-rev-list in your case, you just supply:

  • The number of commits to include, or -1 for only the most recent,
  • The branch (or commit id) to start looking back from, HEAD if you are already on it, or --all if you want all known commits, and
  • The relative path to your file.

This just returns the most recent commit ID in the current branch to alter that file, ex: 215095e2e338525be0baeeebdf66bfbb304e7270

For a more complex example, you can use tag names, and even remote references, and include relative path names with wildcards, for ex:

git rev-list origin/user/bob/testbranch -1 src/bfiles/*.txt

...Which would tell you what the most recent change was to the wildcard match in that branch's history. The options for rev-list are extreme, it is one of the most important plumbing commands, so you can include or exclude by just about any criteria you can imagine.

Of course, refer to the git-rev-list(1) Manual Page.

Solution 3 - Git

If you want to just get the hash of the latest commit to modify a specific set of files (and want to avoid awk) you can use:

git log -n 1 --pretty=format:%h -- <path>

This can be useful for getting the commit hash for subsequently using with git describe.

For example (in case it's useful for anyone)…

I create a current version id by considering the latest commit to change any source file (assuming you mark versions with tags like mycode-1.2.1):

COMMIT=$(git log -n 1 --pretty=format:%h -- *.c *.h)
if VN=$(git describe --always --abbrev=5 --match "mycode-*" $COMMIT 2>/dev/null) &&
case "$VN" in
mycode-*)
	git update-index -q --refresh
	test -z "$(git diff-index --name-only HEAD *.c *.h)" ||
	VN="$VN-mod" ;;
*) VN="mycode-unknown-g$VN" ;;
esac
then
    continue
else
VN="mycode-unknown"
fi

This produces ids like:

  • mycode-1.2.1 - when the current state of the source files corresponds to a tagged version
  • mycode-1.2.1-g3k7s2 - when the current state of the source files corresponds to commit following a tagged version
  • mycode-1.2.1-g3k7s2-mod - when the current state of the source files have been modified since the last commit following a tagged version
  • mycode-unknown - when there has not yet been a version tag created

Solution 4 - Git

I'm not sure if this is what you want but if you do a git log <thefile> to get the commits that altered that file. You can pick the topmost one. It should be the one you're looking for.

Solution 5 - Git

Once you have the SHA id of the commit you want to look at using git log FILENAME, you should be able to do git show SHA_ID_HERE to see what you did for that particular commit. You don't even need to enter the entire ID; the first 6 characters should be enough.

Solution 6 - Git

To get just the ref on one line, try:

git log -n1 --oneline <path> | awk '{print $1;}'

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
QuestionCory KleinView Question on Stackoverflow
Solution 1 - GitJo LissView Answer on Stackoverflow
Solution 2 - GitMichael EricksonView Answer on Stackoverflow
Solution 3 - GitTheBamfView Answer on Stackoverflow
Solution 4 - GitNoufal IbrahimView Answer on Stackoverflow
Solution 5 - GitJoeView Answer on Stackoverflow
Solution 6 - GitfastmultiplicationView Answer on Stackoverflow