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 开发者_JAVA技巧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 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.
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.
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 versionmycode-1.2.1-g3k7s2
- when the current state of the source files corresponds to commit following a tagged versionmycode-1.2.1-g3k7s2-mod
- when the current state of the source files have been modified since the last commit following a tagged versionmycode-unknown
- when there has not yet been a version tag created
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.
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.
To get just the ref on one line, try:
git log -n1 --oneline <path> | awk '{print $1;}'
精彩评论