29

The long SHA can be gotten like below:

repo = git.Repo(search_parent_directories=True)
sha = repo.head.object.hexsha

Or, in git 3.1.7:

sha = repo.head.commit.hexsha

How about short one? (short SHA is decided by the scale of the repo, so it should not be like sha[:7])

0

6 Answers 6

25

As far as I can tell, the gitpython Commit object does not support the short sha directly. However, you can use still gitpython's support for calling git directly to retrieve it (as of git 3.1.7):

repo = git.Repo(search_parent_directories=True)
sha = repo.head.commit.hexsha
short_sha = repo.git.rev_parse(sha, short=4)

This is the equivalent of running

git rev-parse --short=4 ...

on the command-line, which is the usual way of getting the short hash. This will return the shortest possible unambiguous hash of length >= 4 (You could pass in a smaller number, but since git's internal min is 4 it will have the same effect).

Sign up to request clarification or add additional context in comments.

9 Comments

Thank you. actually, i don't want to use shell command, because it makes script run much more slowly.. maybe fixed length of hash does work in most cases, so i will use it.
Hmm... do you mean shelling out yourself directly or using the git-command database internal to gitpython? Using repo.git.revparse() like I suggested does the latter, and should be really fast. If your concern is the memory consumption or spawning new procs, you can instead use git.Repo(odbt=GitDB) for a pure-python solution, though it runs 2-5 times slower.
It seems that repo.head.object.hexsha does not call shell command, and this is ideal one. because I'm correcting git status information to display it in shell prompt. (so it should be fast)
> "Using repo.git.revparse() like I suggested does the latter" really. I didn't know that, thanks.
Actually, small correction; looks like if you are using python > 2.4, it will default to gitdb, which is pure-python, but in any event, using repo.git will still run commands via Popen. Still internal to gitpython though
|
8

For gitpython 3.1.15, there seems to be a shorter way of getting the hash compared to the other answers.

You can simply do

hash = repo.git.rev_parse(repo.head, short=True)

You do not need explicitly obtain

sha = repo.head.commit.hexsha

first.

1 Comment

You can also use repo.git.rev_parse('HEAD', short=True).
6

You will need to use the short argument of rev-parse here to generate the smallest SHA that can uniquely identify the commit. Basically, the short will call the internal git API and return the shortest possible length string for the SHA which can uniquely identify the commit, even if you've passed a very small value for short. So effectively, you can do something like below, which will give you the shortest SHA always (I use short=1 to emphasize that):

In [1]: import git
In [2]: repo = git.Repo(search_parent_directories=True)
In [3]: sha = repo.head.object.hexsha
In [4]: short_sha = repo.git.rev_parse(sha, short=1)
In [5]: short_sha
Out[5]: u'd5afd'

You can read more about this from the git side here. Also, as mentioned in the man-page for git-rev-parse, --short will by default take 7 as its value, and minimum 4.

--short=number

Instead of outputting the full SHA-1 values of object names try to abbreviate them to a shorter unique name. When no length is specified 7 is used. The minimum length is 4.

Comments

3

actually, you need to use

short_sha = repo.git.rev_parse(sha, short=True)

short=4 always shows 4 letter hash even in my ginormous git base

1 Comment

From the git-rev-parse docs: "--short[=length] Same as --verify but shortens the object name to a unique prefix with at least length characters. The minimum length is 4, the default is the effective value of the core.abbrev configuration variable (see git-config[1])." Presumably you are getting 4 length hashes because it is still unique in your repo
-1

The answers already supplied assume you are calling rev-parse through the shell, which is slow. If you already have a reference to the repo, you can do this by accessing the name_rev property on the Commit object with string truncation as follows. The reference is fixed at the length you supply (here, 8), but it works:

repo.remotes.origin.refs['my/branch/name'].object.name_rev[:8]

The actual output of this command is the full sha, followed by a space, followed by the branch name.

3 Comments

I don't know what answers you are talking about since literally not a single one calls it through the shell. This solution is also pretty bad because it uses a fixed length of the commit hash which does not have the uniqueness property the rev_parse solution has.
@StefanFabian the answers that mention repo.git end up calling it through the shell under the hood: gitpython.readthedocs.io/en/stable/…
Ah sorry, you are right! The point that you might need more than 8 characters to preserve uniqueness still stands but I'd like to apologize for the tone. Apart from this, performance-wise this is a great solution.
-1

Current answer is outdated and the way to retrie sha of the commit is commit.hexsha.

1 Comment

This is not a standalone answer to the question of getting a short hash, and is really only relevant as a comment on the outdated answer mentioned.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.