get short sha of commit with gitpython
Asked Answered
G

6

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])

Gauntry answered 12/8, 2015 at 5:11 Comment(0)
H
24

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).

Hospers answered 12/8, 2015 at 6:21 Comment(9)
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.Gauntry
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.Hospers
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)Gauntry
> "Using repo.git.revparse() like I suggested does the latter" really. I didn't know that, thanks.Gauntry
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 thoughHospers
So, without Popen, it is impossible to get shortened hash. I'm using fixed length. thanks.Gauntry
This answer should define the sha variable like @mu did below in order to be completeMoisten
As someone also mentioned there is a way of doing it https://mcmap.net/q/484026/-get-short-sha-of-commit-with-gitpythonFitful
@Fitful As per gitpython 3.17 documentation commit.hexsha still returns the full 40 byte hex version rather than the short version -- I think git.rev_parse() remains the valid way to do this. I've added how to get at the long sha in the latest gitpythonHospers
W
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.

Wehrmacht answered 12/8, 2015 at 6:42 Comment(0)
B
6

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.

Buckram answered 10/5, 2021 at 12:7 Comment(1)
You can also use repo.git.rev_parse('HEAD', short=True).Jejune
T
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

Tessin answered 23/4, 2020 at 15:34 Comment(1)
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 repoHospers
A
-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.

Acred answered 28/1, 2016 at 13:41 Comment(3)
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.Peduncle
@StefanFabian the answers that mention repo.git end up calling it through the shell under the hood: gitpython.readthedocs.io/en/stable/…Acred
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.Peduncle
F
-1

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

Fitful answered 17/8, 2020 at 15:16 Comment(1)
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.Scanner

© 2022 - 2024 — McMap. All rights reserved.