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 log
supports looking at the history of specific files (and directories), so you can call it like this:
git log path/to/file
Tip: Whenever I look at the history of a specific file, I tend to also want to see the diffs, by passing -p
(or --patch
):
git log -p path/to/file
If you want only the commit hash for use in a script, git rev-list
is the more appropriate low-level command (thanks Michael Erickson):
git rev-list -1 HEAD -- path/to/file
Here's what the options mean:
-1
: Limit to 1 commit (the most recent one).HEAD
: Walk backwards from the current HEAD
commit.--
: Separator in case the file name happens to be a valid commit name.path/to/file
: The file path(s).Passing HEAD
here makes it behave like git log
(which starts at HEAD
by default).
--all
, which means it will check all the refs in .git/refs
(as printed by git for-each-ref
) as well as HEAD
. (Thanks K. C.)When specifying multiple branches that have diverged, or when the commit graph branches because of a merge, which commit counts as "most recent"? This is where the traversal order logic becomes relevant. The details are a bit tricky, but in most cases it basically does what you expect:
git rev-list
will always respect the topological order of the commit graph -- that is, parents are never visited before all of their children have been visited. But when it has a choice (e.g. walking the ancestors of a merge commit), it will interleave both paths by commit timestamp order (--date-order
, the default) until it has reached a common ancestor. It immediately stops traversing once it has found a commit that modifies the file.
Preserving my previous answer for the shell scripting case here: You could also use the git log -n 1
option to limit it to one commit:
git log -n 1 --format=%H -- path/to/file
--format=%H
tells git log
to show only the commit hash.
I don't recommend git log
for this, however, because it uses user-facing "porcelain" commands instead of lower-level "plumbing" commands.