题 如何在Git中检索当前提交的哈希值?


我想保留(现在)将Git变更集链接到存储在TFS中的工作项的功能。

我已经编写了一个工具(使用Git中的一个钩子),我可以在其中将workitemidentifiers注入到Git变更集的消息中。

但是,我还想将Git提交的标识符(哈希)存储到自定义TFS工作项字段中。通过这种方式,我可以检查TFS中的工作项,并查看与工作项相关联的Git更改集。

如何从Git的当前提交中轻松检索哈希?


1418
2018-06-04 08:42


起源




答案:


要将任意扩展对象引用转换为SHA-1,请使用简单 GIT-REV-解析, 例如

git rev-parse HEAD

要么

git rev-parse --verify HEAD

边注: 如果你想转 引用 (分支机构 和 标签)进入SHA-1,有 git show-ref 和 git for-each-ref


2073
2018-06-04 09:05



--verify 暗示: The parameter given must be usable as a single, valid object name. Otherwise barf and abort. - Linus Unnebäck
git rev-parse --short HEAD 返回哈希的简短版本,以防万一有人想知道。 - Thane Brimhall
除了Thane所说的,你还可以添加一个特定的长度 --short, 如 --short=12,从哈希中获取特定数量的数字。 - Tyson Phalp
@TysonPhalp: --short=N 是关于 最小 位数;如果缩短的数字与缩短的其他提交无法区分,则git使用更多的数字。尝试例如 git rev-parse --short=2 HEAD要么 git log --oneline --abbrev=2。 - Jakub Narębski
除了Thane,Tyson和Jakub所说的,你可以打印完整的哈希,但突出显示提交蓝色所需的六角形 git rev-parse HEAD | GREP_COLORS='ms=34;1' grep $(git rev-parse --short=0 HEAD) - Zaz


如果您只想要缩短的哈希:

git log --pretty=format:'%h' -n 1

此外,使用%H是另一种获取长哈希的方法。


325
2017-09-30 23:32



或者,似乎在上面的rev-parse命令中添加--short似乎可行。 - outofculture
我认为 git log 是瓷器和 git rev-parse 是管道。 - Amedee Van Gasse
这种方法的一个好处是它将返回哈希的短版本,其长度调整为适用于更大回购的哈希冲突。至少在最新版本的git中。 - Ilia Sidorenko
这是一种错误/不正确的方法,因为如果你有一个分离的头,这个方法会给你错误的哈希。例如,如果当前提交是12ab34 ...并且之前的提交是33aa44 ...那么如果我做'git checkout 33aa44'然后我运行你的命令我仍然会回到12ab34 ...尽管我的头实际指向到33aa44 ...... - theQuestionMan
@theQuestionMan我没有经历你描述的行为; git checkout 33aa44; git log -n 1 给我 33aa44。你用的是什么版本的git? - outofculture


另一个,使用git日志:

git log -1 --format="%H"

它与@outofculture非常相似,虽然有点短。


116
2017-11-21 18:48



结果不是单引号。 - crokusek


为了完整起见,因为还没有人建议它。 .git/refs/heads/master 是一个只包含一行的文件:最新提交的哈希值 master。所以你可以从那里读取它。

或者,如命令:

cat .git/refs/heads/master

更新:

请注意,git现在支持在pack-ref文件中存储一些头部引用,而不是在/ refs / heads /文件夹中存储文件。 https://www.kernel.org/pub/software/scm/git/docs/git-pack-refs.html


62
2017-10-16 11:34



这假定当前分支是 master,这不一定是真的。 - gavrie
确实。这就是我明确表示这是为什么的原因 master。 - Deestan
.git/HEAD 通常指向一个ref,如果你有一个SHA1,你处于分离头模式。 - eckes
与其他方法相比,这不是非常强大,特别是因为它假设存在 .git 子目录,不一定是这种情况。见 --separate-git-dir 国旗在 git init 手册页。 - jubobs
+1因为有时你不想安装git可执行文件(例如在你的Dockerfile中) - wim


要获得完整的SHA:

$ git rev-parse HEAD
cbf1b9a1be984a9f61b79a05f23b19f66d533537

要获得缩短版本:

$ git rev-parse --short HEAD
cbf1b9a

58
2017-07-29 20:04





永远都是 git describe 同样。默认情况下它会给你 -

john@eleanor:/dev/shm/mpd/ncmpc/pkg (master)$ git describe 
release-0.19-11-g7a68a75

34
2017-08-26 10:43



Git describe返回从提交可到达的第一个TAG。这有助于我获得SHA? - Sardaukar
我喜欢 git describe --long --dirty --abbrev=10 --tags 它会给我一些类似的东西 7.2.0.Final-447-g65bf4ef2d4 在7.2.0.Final标签之后是447次提交,当前HEAD的全局SHA-1的前10个摘要是“65bf4ef2d4”。这对版本字符串非常有用。使用--long它将始终添加计数(-0-)和散列,即使标签恰好匹配。 - eckes
如果没有标签那么 git describe --always 将“显示唯一缩写的提交对象作为后备” - Ronny Andersson


提交哈希

git show -s --format=%H

缩写提交哈希

git show -s --format=%h

点击 这里 更多 git show 例子。


25
2018-03-27 19:33





使用 git rev-list --max-count=1 HEAD


24
2018-06-04 08:48



git-rev-list是关于生成提交对象的列表;将对象名称(例如HEAD)转换为SHA-1是git-rev-parse - Jakub Narębski


如果您需要在脚本期间将哈希存储在变量中,则可以使用

last_commit=$(git rev-parse HEAD)

或者,如果你只想要前10个字符(比如github.com)

last_commit=$(git rev-parse HEAD | cut -c1-10) 

18
2017-07-15 16:04



还有 --short要么 --short=number 参数来 git rev-parse;不需要使用管道和 cut。 - Julian D.


我知道的最简洁的方式:

git show --pretty=%h 

如果您想要添加哈希的特定位数,可以添加:

--abbrev=n

12
2018-02-07 06:43



虽然这在技术上有效, git show 是所谓的瓷器命令(即面向用户),所以应该如此 不 在脚本中使用,因为它的输出可能会发生变化。上面的答案(git rev-parse --short HEAD)应该用来代替。 - jm3
@ jm3那是倒退的。 “Porcelain”命令具有稳定的输出,用于脚本。搜索 git help show 对于 porcelain。 - John Tyree
@JohnTyree doh,你是对的,我的错。 - jm3


如果你想要超级黑客的方式:

cat .git/`cat .git/HEAD | cut -d \  -f 2`

基本上,git将HEAD的位置存储在表单中的.git / HEAD中 ref: {path from .git}。该命令将其读出,切掉“ref:”,并读出它指向的任何文件。

当然,这将在分离头模式下失败,因为HEAD不会是“ref:...”,而是散列本身 - 但是你知道,我认为你不希望你的bash中有那么多聪明的东西-liners。如果你不认为分号是作弊,但......

HASH="ref: HEAD"; while [[ $HASH == ref\:* ]]; do HASH="$(cat ".git/$(echo $HASH | cut -d \  -f 2)")"; done; echo $HASH

10
2017-10-14 19:15



不需要安装git,我喜欢它。 (我的码头构建图像没有git) - Helin Wang
也很有用,因为你可以从git repo外部轻松运行 - samaspin
我把它正式化为我本地机器的脚本。然后,我想,嘿:我所做的实现很简单,它说明了如何解决一个不相关的问题(在没有外部程序的情况下解析原始POSIX shell脚本中的参数),但复杂到足以提供一点变化并利用大部分特点 sh。半小时的文档评论稍后,这里是它的要点: gist.github.com/Fordi/29b8d6d1ef1662b306bfc2bd99151b07 - Fordi
看一下,我做了一个更广泛的版本来检测Git和SVN,并获取git hash / svn版本。这次不是一个干净的字符串,但可以轻松解析命令行,并可用作版本标记: gist.github.com/Fordi/8f1828efd820181f24302b292670b14e - Fordi