使用GitPython获取提交的短SHA码

25

长SHA可以像下面这样获取:

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

或者,在 git 3.1.7 中:

sha = repo.head.commit.hexsha

短的怎么样? (短的SHA由代码库的规模决定,所以不应该像sha[:7]那样)

6个回答

21
据我所知,gitpython的Commit对象似乎不支持直接获取短SHA。但是,你仍然可以利用gitpython对于直接调用git的支持来检索它(截至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)

这相当于运行

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

在命令行上通常通过获取短哈希的方式来执行此操作。这将返回长度>= 4的最短可能的无歧义哈希值(您可以传递较小的数字,但由于git的内部最小值为4,因此效果相同)。


谢谢。实际上,我不想使用shell命令,因为它会使脚本运行得更慢。也许在大多数情况下固定长度的哈希值可以解决问题,所以我会使用它。 - Kentaro Wada
嗯...你是指直接使用shell还是使用gitpython内部的git命令数据库?像我建议的那样使用repo.git.revparse()可以实现后者,并且速度应该非常快。如果你担心内存消耗或产生新进程,你可以使用git.Repo(odbt=GitDB)来获得一个纯Python解决方案,尽管它运行速度会慢2-5倍。 - lemonhead
似乎repo.head.object.hexsha不会调用shell命令,这是非常理想的。因为我正在纠正git状态信息以在shell提示符中显示它。(因此应该很快) - Kentaro Wada
“像我建议的那样使用repo.git.revparse()确实可以做到后者。” 真的吗?我不知道,谢谢。 - Kentaro Wada
所以,没有Popen,就不可能获取缩短的哈希值。我正在使用固定长度。谢谢。 - Kentaro Wada
显示剩余4条评论

6
您需要在这里使用rev-parse命令的short参数来生成尽可能短的SHA,以唯一标识提交。基本上,short将调用内部git API并返回一个最短可能的字符串长度的SHA来唯一标识提交,即使您传递了非常小的值。因此,您可以执行以下操作,它将始终给您最短的SHA(我使用short=1来强调):
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'

您可以从git的角度在此处了解更多。另外,如git-rev-parse的man-page所述,--short默认会将其值设为7,并且最小值为4。

--short=number

不输出对象名称的完整SHA-1值,而是缩写为较短的唯一名称。当未指定长度时,默认使用7。最小长度为4。


5

对于gitpython 3.1.15,相比其他答案,有一种更短的方法可以获取哈希值。

你只需执行以下操作:

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

您不需要明确获取
sha = repo.head.commit.hexsha

首先。


你也可以使用repo.git.rev_parse('HEAD', short=True) - idbrii

3

实际上,您需要使用

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

short=4总是显示4个字母的哈希,即使在我的庞大git库中也是如此。


git-rev-parse文档中:"--short[=length] 与--verify相同,但将对象名称缩短为具有至少长度字符的唯一前缀。最小长度为4,默认值为core.abbrev配置变量的有效值(参见git-config[1])。可能是因为在您的存储库中仍然是唯一的,所以您会得到4个长度的哈希值。 - lemonhead

-1

当前的答案已经过时了,获取提交的哈希值的方法是commit.hexsha


这不是获取短哈希的独立答案,实际上只是针对提到的过时答案的评论。 - AnnanFay

-1

已经提供的答案假定您通过 shell 调用 rev-parse,这很慢。如果您已经有了对 repo 的引用,可以通过访问 Commit 对象上的 name_rev 属性并使用字符串截断来执行此操作。参考文献在您提供的长度(这里为 8)处固定,但它有效:

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

该命令的实际输出是完整的SHA码,后跟一个空格,然后是分支名称。


我不知道你说的答案是什么,因为没有一个答案是通过 shell 调用的。这个解决方案也相当糟糕,因为它使用了固定长度的提交哈希值,其唯一性属性不如 rev_parse 解决方案。 - Stefan Fabian
@StefanFabian提到repo.git的答案最终会通过底层的shell来调用它:https://gitpython.readthedocs.io/en/stable/tutorial.html#using-git-directly - Myer
啊,对不起,你是对的!关于保持唯一性可能需要超过8个字符的观点仍然存在,但我想为语气向你道歉。除此之外,就性能而言,这是一个很好的解决方案。 - Stefan Fabian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接