How to retrieve the hash for the current commit in Git?
Solution 1
To turn arbitrary extended object reference into SHA-1, use simply git-rev-parse, for example
git rev-parse HEAD
or
git rev-parse --verify HEAD
You can also retrieve the short version like this
git rev-parse --short HEAD
Sidenote: If you want to turn references (branches and tags) into SHA-1, there is git show-ref
and git for-each-ref
.
Solution 2
If you only want the shortened commit hash:
git log --pretty=format:'%h' -n 1
Furthermore, using %H
is another way to get the long commit hash, and simply -1
can be used in place of -n 1
.
Solution 3
Another one, using git log:
git log -1 --format="%H"
It's very similar to the of @outofculture though a bit shorter.
Solution 4
To get the full SHA:
$ git rev-parse HEAD
cbf1b9a1be984a9f61b79a05f23b19f66d533537
To get the shortened version:
$ git rev-parse --short HEAD
cbf1b9a
Solution 5
For completeness, since no-one has suggested it yet. .git/refs/heads/master
is a file that contains only one line: the hash of the latest commit on master
. So you could just read it from there.
Or, as as command:
cat .git/refs/heads/master
Update:
Note that git now supports storing some head refs in the pack-ref file instead of as a file in the /refs/heads/ folder. https://www.kernel.org/pub/software/scm/git/docs/git-pack-refs.html
Sardaukar
Thinks that software development is part science, part art (is just not sure which part is bigger).
Updated on July 29, 2022Comments
-
Sardaukar almost 2 years
I would like to retain (for now) the ability to link Git changesets to workitems stored in TFS.
I already wrote a tool (using a hook from Git) in which I can inject workitem identifiers into the message of a Git changeset.
I would also like to store the hash of the Git commit in a custom TFS workitem field. This way I can examine a workitem in TFS and see what Git changesets are associated with the workitem.
How can I easily retrieve the hash from the current commit from Git?
-
Anonigan about 15 yearsgit-rev-list is about generating list of commit objects; it is git-rev-parse to translate object name (e.g. HEAD) into SHA-1
-
Linus Unnebäck almost 13 years
--verify
implies that:The parameter given must be usable as a single, valid object name. Otherwise barf and abort.
-
Sardaukar almost 13 yearsGit describe returns the first TAG reachable from a commit. How does this help me get the SHA?
-
outofculture over 12 yearsOr, it seems, adding --short to the rev-parse command above seems to work.
-
gavrie over 11 yearsThis assumes the current branch is
master
, which is not necessarily true. -
futurecat over 11 yearsIndeed. That's why I explicitly said this is for
master
. -
Thane Brimhall over 11 years
git rev-parse --short HEAD
returns the short version of the hash, just in case anyone was wondering. -
kynan over 11 yearsThere is
.git/HEAD
which is a file that contains 1 line with the SHA1 of HEAD. I think that's what you meant. -
Prashant about 11 yearsI like
git describe --long --dirty --abbrev=10 --tags
it will give me something like7.2.0.Final-447-g65bf4ef2d4
which is 447 commits after the 7.2.0.Final tag and the first 10 digest of the global SHA-1 at the current HEAD are "65bf4ef2d4". This is very good for version strings. With --long it will always add the count (-0-) and the hash, even if the tag happens to match exactly. -
Prashant about 11 years
.git/HEAD
typically points to a ref, if you have a SHA1 in there, you are in detached head mode. -
Tyson Phalp over 10 yearsAdding to what Thane said, you can also add a specific length to
--short
, such as--short=12
, to get a specific number of digits from the hash. -
Anonigan over 10 years@TysonPhalp:
--short=N
is about minimal number of digits; git uses larger number of digits if shortened one would be undistinguishable from shortened other commit. Try e.g.git rev-parse --short=2 HEAD
orgit log --oneline --abbrev=2
. -
jm3 over 10 yearsWhile this technically works,
git show
is what's known as a porcelain command (i.e. user-facing), and so should not be used in scripts because its output is subject to change. The answer above (git rev-parse --short HEAD
) should be used instead. -
Zaz almost 10 yearsAdding to what Thane, Tyson, and Jakub said, you can print the full hash, but highlight the hexits necessary to identify the commit blue with
git rev-parse HEAD | GREP_COLORS='ms=34;1' grep $(git rev-parse --short=0 HEAD)
-
Ronny Andersson almost 10 yearsIf no tags exist then
git describe --always
will "show uniquely abbreviated commit object as fallback" -
jub0bs over 9 yearsThis isn't very robust compared to other approaches, in particular because it assumes that there is a
.git
subdirectory, which is not necessarily the case. See the--separate-git-dir
flag in thegit init
man page. -
wim about 9 years+1 because sometimes you don't want git executable installed (e.g. in your Dockerfile)
-
pushya about 9 yearsFor finding the SHA- hash of a branch
.git/refs/heads/<branch-name>
-
John Tyree almost 9 years@jm3 that's backwards. "Porcelain" commands have stable outputs that are intended for scripts. Search
git help show
forporcelain
. -
XP84 almost 9 yearsNeat trick Zaz. It doesn't seem to work with the grep on my Mac, but I substituted
ack
for a similar effect! -
Theodore Murdock over 8 years@Zaz That didn't work for me either, but simply
git rev-parse HEAD | grep --color $(git rev-parse --short=0 HEAD)
does. -
Amedee Van Gasse over 8 yearsI think
git log
is porcelain andgit rev-parse
is plumbing. -
Helin Wang over 8 yearsno need to install git, I like it. (my docker build image does not have git)
-
Aaron about 8 yearsIs there a way to do this but on a per-directory basis? For example, lets say I want the latest hash of a particular directory. Do I need to do a
git log <directory>
and parse it out to grab the hash? -
Anonigan about 8 years@Aaron: roughly speaking yes, you need to run
git log <options> -- <directory>
; but you can configure git-log so it returns only hash. -
nhed about 8 years+1 -and- if you don't want to necessarily pull/rebase/merge and just want to get hash post-fetch
cat .git/refs/remotes/origin/master
-
Halil about 8 yearsAdding to what @ThaneBrimhall said, you can get the full SHA-1 reference from the short version of the hash using
git rev-parse ca003ae
. -
samaspin about 8 yearsalso useful because you can run this easily from outside the git repo
-
Fordi almost 8 yearsI formalized this to a script for my local machine. Then, I thought, hey: the implementation I made are simple enough that it illustrates how to solve an unrelated problem (parsing arguments in raw POSIX shell scripts without external programs), but complex enough to provide a little variation and to exploit most of the features of
sh
. Half an hour of documentation comments later, and here's a Gist of it: gist.github.com/Fordi/29b8d6d1ef1662b306bfc2bd99151b07 -
Fordi almost 8 yearsLooking at it, I made a more extensive version for detecting Git and SVN, and grabbing the git hash/svn revision. Not a clean string this time, but easily command-line parsed, and usable as a version tag: gist.github.com/Fordi/8f1828efd820181f24302b292670b14e
-
Sap almost 8 yearsDoes this way work if you have a tag named "HEAD"? >:)
-
Anonigan almost 8 years@EdRandall:
git rev-parse
main goal is to parse parameters and return revisions, so--short
means shortened SHA-1 of revision.git log
return more information, which includes SHA-1 of revisions, that can be abbreviated with--abbrev
or--abbrev-commit
. -
Ilia Sidorenko over 7 yearsOne of the benefits of this method is that it will return the short version of the hash with the right length adjusted to the hash collisions which happen for larger repos. At least in recent versions of git.
-
crokusek over 7 yearsAnd the result is not single-quoted.
-
theQuestionMan almost 7 yearsThis is a bad/ incorrect way of doing it because this method will give you the wrong hash if you have a detached head. For example if the current commit is 12ab34... and the previous commit was 33aa44... then if i do 'git checkout 33aa44' and then I run your command I will still be getting back 12ab34... despite my head actually pointing to 33aa44...
-
outofculture almost 7 years@theQuestionMan I don't experience the behavior you describe;
git checkout 33aa44; git log -n 1
gives me33aa44
. What version of git are you using? -
Kirk Strobeck almost 7 years
git rev-parse HEAD | pbcopy
is great for quick clipboard’ing on mac -
milkovsky over 6 yearsCool! I have even added it to alias:
git config --global alias.sha 'rev-parse HEAD'
. Now I can simply usegit sha
. -
hakre over 6 yearsThanks, just stumbling over it and it spares me the one or other echo for that :)
-
sschueller about 6 yearsThis is answer is not always correct! If the HEAD is not at the your checkout commit (detached head) what you get back is incorrect. Only
git status
will give you the correct commit hash. -
Keyur Padalia almost 6 yearsIt works for me without the
--match "NOT A TAG"
. Tested in git 2.18.0 as well as 2.7.4. Is there any situation where this argument is needed? -
Peter Hlavatík almost 6 years@Thomas it won't work if you have an annotated tag anywhere in the history of the current commit. The fake tag makes sure that the describe command does not use a tag to describe the commit,
-
Mike almost 6 yearsIf two
git
commit
hashes are needed, such as one from thebranch
you are currently working with and amaster
branch
, you could also usegit rev-parse FETCH_HEAD
if you need the hash for themaster
commit
that youmerge
d into your currentbranch
. e.g. if you havebranch
esmaster
andfeature/new-feature
for a given repo., while onfeature/new-feature
you could usegit fetch origin master && git merge FETCH_HEAD
and thengit rev-parse --short FETCH_HEAD
if you needed thecommit
hash from themaster
you justmerge
d in for any scripts you may have. -
Pont over 5 years
show-ref
seems to me to be the best option for scripting, since it's a plumbing command and thus guaranteed (or at least very likely) to remain stable in future releases: other answers userev-parse
,show
,describe
, orlog
, which are all porcelain commands. And in cases where speed is not of the essence, the note from theshow-ref
manpage applies: ‘Use of this utility is encouraged in favor of directly accessing files under the .git directory.’ -
Fabio says Reinstate Monica over 5 years@JohnTyree This is a confusing subject, but jm3 was right: porcelain commands are not meant to be parsed, but rather to be human-readable. In case you need to use a porcelain command in a script and you want to have a stable format, there's sometimes (for example with git status, push and blame) an option that does just that. Unfortunately, that option is called
--porcelain
, which is why this is confusing. You can find the details in this great answer by VonC -
Tom Ozx over 5 yearsThis is the correct answer, since it works even if you checkout a specific commit instead of
HEAD
. -
ChristofSenn over 4 years@Parsa: when checking out a specific commit
HEAD
points to this commit rather than a named branche know as detached head. -
ingyhere over 4 yearsI use
git describe --tags --first-parent --abbrev=11 --long --dirty --always
. The--always
option means it provides a result (hash) even if there are no tags. The--first-parent
means it doesn't get confused by merge commits and only follows items on the current branch. Note also that--dirty
will append-dirty
to the result if the current branch has uncommitted changes. -
Carlo Wood over 4 yearsThis is less robust because
.git
may always be a file containing the name of the real .git directory. -
sij about 4 years+1 because this may be faster and more straightforward as you don't have to call bash just to display the commit hash in the footer of the GUI.
-
Cheruvim almost 4 yearsI find this doesn't work with non-annotated tags. If you have a non-annotated tag pointing to head,
git rev-parse --short HEAD
should give you the same result asgit show-ref -s7 <tag>
and it doesn't I got two different hashes when doing this. This is because lightweight tags will only show their ref hash not the hash of the commit they are pointing to. You need to dogit rev-parse --short '<tag>^{}'
for that. -
xjcl over 3 yearsWhen do I need
--verify
? -
Anonigan over 3 years@xjcl the
--verify
option is useful if you usegit rev-parse
together with something variable, likegit rev-parse --verify $branch
. Forgit rev-parse --verify HEAD
it ensures that HEAD can be turned into SHA-1 / object identifier (and for example you are not on an unborn branch). -
Patronics over 3 years@AmedeeVanGasse if
git log
is porcelain andgit rev-parse
is plumbing, what isgit status --porcelain
? :P -
Amedee Van Gasse over 3 years@PatrickL I don't know, this is a question from 4 years ago and I don't feel like going back to something that's behind me. I recommend that you open a new question on Stack Overflow.
-
Gabriel Staples over 3 years@AmedeeVanGasse, ah! I HAD NO IDEA this is a toilet analogy! I've been seeing
porcelain
in thegit
man
pages for years, but had NO idea it was referring to a toilet! The porcelain is the toilet, and it's "closer to the user" (who figuratively sits on this toilet) than the plumbing, which is lower-level and farther from the user--ie: below the "porcelain"! Mind blown. -
Gabriel Staples over 3 years@PatrickL, I'd say
git status
is the plastic toilet seat. It's closer to the user than the porcelain, where "porcelain" refers to the porcelain bowl under the toilet seat. So,git status
andgit log
are plastic.git log --pretty=format
is porcelain,git status --porcelain
is also porcelain, andgit rev-parse
is plumbing. -
cdalxndr about 3 yearsFull pretty format options: git-scm.com/docs/pretty-formats#Documentation/…
-
ederag about 3 yearsFrom the command line, to avoid pager:
git --no-pager log -1 --format="%H"
-
squall3d about 3 yearsIf you pass this to pbcopy on mac to copy it into the clipboard, you'll get a new line at the end. To get rid of it, use
git rev-parse HEAD | tr -d '\n' | pbcopy
-
spawn about 2 years@Parsa Your (mistakenly upvoted?) comment is misleading as the accepted answer of jakub-narębski 'git rev-parse HEAD' works after checking out somewhere else.
-
Tom Ozx about 2 years@spawn It's not a mistake. Remember that
HEAD
is just a pointer. As long asHEAD
points to the current commit, which is commonly the case, you are fine; but if you are in a detached state, it's now pointing to a different commit than where you are. -
spawn about 2 years@Parsa - maybe we misunderstand each other: after checkout from commit a1b1 to c1d1
git rev-parse HEAD
prints c1d1. So, HEAD points to the "current commit" which the OP asked for. From your upvoted comment I mistakenly concluded thatgit rev-parse HEAD
was wrong. -
Johannes Deml about 2 yearsSmall caveat for
git rev-parse xxx
: This results inSHA + \n
, so it adds a new line at the very end. So if you want to get just the SHA, be sure to trim your result