【发布时间】:2010-10-31 06:18:29
【问题描述】:
我想保留(目前)将 Git 变更集链接到存储在 TFS 中的工作项的能力。
我已经编写了一个工具(使用来自 Git 的钩子),我可以在其中将工作项标识符注入到 Git 变更集的消息中。
我还想将 Git 提交的哈希值存储在自定义 TFS 工作项字段中。通过这种方式,我可以检查 TFS 中的工作项并查看哪些 Git 变更集与该工作项相关联。
如何轻松地从 Git 的当前提交中检索哈希?
【问题讨论】:
我想保留(目前)将 Git 变更集链接到存储在 TFS 中的工作项的能力。
我已经编写了一个工具(使用来自 Git 的钩子),我可以在其中将工作项标识符注入到 Git 变更集的消息中。
我还想将 Git 提交的哈希值存储在自定义 TFS 工作项字段中。通过这种方式,我可以检查 TFS 中的工作项并查看哪些 Git 变更集与该工作项相关联。
如何轻松地从 Git 的当前提交中检索哈希?
【问题讨论】:
使用git rev-list --max-count=1 HEAD
【讨论】:
要将任意扩展对象引用转换为 SHA-1,只需使用 git-rev-parse,例如
git rev-parse HEAD
或
git rev-parse --verify HEAD
你也可以像这样检索短版
git rev-parse --short HEAD
旁注:如果您想转引用(分支和标签 ) 进入 SHA-1,有git show-ref 和git for-each-ref。
【讨论】:
--verify 暗示:The parameter given must be usable as a single, valid object name. Otherwise barf and abort.
git rev-parse --short HEAD 返回哈希的简短版本,以防万一有人想知道。
--short加上一个特定的长度,比如--short=12,从hash中得到一个特定的位数。
--short=N 大约是最少位数;如果缩短的数字与缩短的其他提交无法区分,则 git 使用更多的数字。尝试例如git rev-parse --short=2 HEAD 或 git log --oneline --abbrev=2.
git rev-parse HEAD | GREP_COLORS='ms=34;1' grep $(git rev-parse --short=0 HEAD) 突出显示蓝色提交所必需的十六进制数
也总是有git describe。默认情况下,它会为您提供 --
john@eleanor:/dev/shm/mpd/ncmpc/pkg (master)$ git describe --always
release-0.19-11-g7a68a75
【讨论】:
git describe --long --dirty --abbrev=10 --tags 它会给我类似7.2.0.Final-447-g65bf4ef2d4 之类的东西,这是在 7.2.0.Final 标记和当前 HEAD 处全局 SHA-1 的前 10 个摘要之后的 447 次提交“65bf4ef2d4”。这对于版本字符串非常有用。使用 --long 它总是会添加计数 (-0-) 和哈希,即使标签恰好匹配。
git describe --always 将“将唯一缩写的提交对象显示为备用”
git describe --tags --first-parent --abbrev=11 --long --dirty --always。 --always 选项意味着即使没有标签,它也会提供结果(哈希)。 --first-parent 意味着它不会被合并提交弄糊涂,并且只关注当前分支上的项目。另请注意,如果当前分支有未提交的更改,--dirty 会将-dirty 附加到结果中。
如果你只想要缩短的提交哈希:
git log --pretty=format:'%h' -n 1
此外,使用%H 是另一种获取长提交哈希的方法,只需使用-1 代替-n 1。
【讨论】:
git log 是瓷器,git rev-parse 是管道。
git checkout 33aa44; git log -n 1 给了我33aa44。你用的是什么版本的git?
git man 页面中看到porcelain,但不知道它指的是厕所!瓷器就是马桶,它比水管“更接近使用者”(形象地坐在这个马桶上),而水管更下层,离使用者更远——即:在“瓷器”之下!大吃一惊。
另一个,使用 git log:
git log -1 --format="%H"
它与@outofculture 非常相似,但更短一些。
【讨论】:
HEAD,它仍然有效。
HEAD 指向此提交,而不是称为 detached head 的命名分支。
git --no-pager log -1 --format="%H"
如果您需要在脚本期间将哈希存储在变量中,您可以使用
last_commit=$(git rev-parse HEAD);
或者,如果您只想要前 10 个字符(例如 github.com)
last_commit=$(git rev-parse --short=10 HEAD);
【讨论】:
为了完整起见,因为还没有人提出建议。 .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
【讨论】:
master,这不一定是真的。
master。
.git/HEAD 通常指向一个 ref,如果你有一个 SHA1,你就处于分离头模式。
.git 子目录,但不一定如此。请参阅 git init 手册页中的 --separate-git-dir 标志。
我知道的最简洁的方式:
git show --pretty=%h
如果您想要特定位数的哈希,您可以添加:
--abbrev=n
【讨论】:
git show 是所谓的瓷器命令(即面向用户),因此不应在脚本中使用,因为它的输出是主题改变。应该改用上面的答案(git rev-parse --short HEAD)。
git help show 中搜索porcelain。
--porcelain,这就是为什么这令人困惑。您可以在this great answer by VonC中找到详细信息
git show-ref --head --hash head
如果你追求速度,the approach mentioned by Deestan
cat .git/refs/heads/<branch-name>
比迄今为止列出的任何其他方法都快得多。
【讨论】:
show-ref 在我看来是编写脚本的最佳选择,因为它是一个管道命令,因此保证(或至少很可能)在未来的版本中保持稳定:其他答案使用 rev-parse 、show、describe 或log,这些都是瓷器命令。如果速度不是的本质,show-ref 手册页中的注释适用:“鼓励使用此实用程序,以支持直接访问 .git 目录下的文件。”跨度>
也许您想要一个别名,这样您就不必记住所有漂亮的细节。执行以下步骤之一后,您将能够简单地键入:
$ git lastcommit
49c03fc679ab11534e1b4b35687b1225c365c630
跟进accepted answer,这里有两种设置方法:
1)通过编辑全局配置(我的原始答案)以显式方式教 git:
# open the git config editor
$ git config --global --edit
# in the alias section, add
...
[alias]
lastcommit = rev-parse HEAD
...
2) 或者,如果您喜欢教 git 捷径的捷径,正如 Adrien 最近评论的那样:
$ git config --global alias.lastcommit "rev-parse HEAD"
从这里开始,使用git lastcommit 显示最后一次提交的哈希。
【讨论】:
如果你想要超级 hacky 的方法:
cat .git/`cat .git/HEAD | cut -d \ -f 2`
基本上,git 将 HEAD 的位置存储在 .git/HEAD 中,格式为 ref: {path from .git}。该命令将其读取出来,切掉“ref:”,然后读取它指向的任何文件。
当然,这在分离头模式下会失败,因为 HEAD 不会是“ref:...”,而是哈希本身 - 但你知道,我认为你不会期望在你的 bash 单线。不过,如果您不认为分号作弊...
HASH="ref: HEAD"; while [[ $HASH == ref\:* ]]; do HASH="$(cat ".git/$(echo $HASH | cut -d \ -f 2)")"; done; echo $HASH
【讨论】:
sh 的特点。半小时后的文档 cmets,这里有一个要点:gist.github.com/Fordi/29b8d6d1ef1662b306bfc2bd99151b07
在文件“.gitconfig”的主目录中添加以下内容
[alias]
sha = rev-parse HEAD
那么你将有一个更容易记住的命令:
$ git sha
59fbfdbadb43ad0b6154c982c997041e9e53b600
【讨论】:
要获得完整的 SHA:
$ git rev-parse HEAD
cbf1b9a1be984a9f61b79a05f23b19f66d533537
要获得缩短版:
$ git rev-parse --short HEAD
cbf1b9a
【讨论】:
git commit 哈希,例如一个来自您当前正在使用的 branch 和一个 master branch,您也可以使用 git rev-parse FETCH_HEAD 如果您需要将 merged 的 master commit 的哈希值转换为当前的 branch。例如如果你有 branches master 和 feature/new-feature 对于给定的回购。而在 feature/new-feature 你可以使用 git fetch origin master && git merge FETCH_HEAD 然后 git rev-parse --short FETCH_HEAD 如果你需要来自 master 的 commit 哈希你只需 merged 输入您可能拥有的任何脚本。
这是另一个直接访问实现:
head="$(cat ".git/HEAD")"
while [ "$head" != "${head#ref: }" ]; do
head="$(cat ".git/${head#ref: }")"
done
这也适用于 http,这对于本地包存档很有用(我知道:对于公共网站,不建议使 .git 目录可访问):
head="$(curl -s "$baseurl/.git/HEAD")"
while [ "$head" != "${head#ref: }" ]; do
head="$(curl -s "$baseurl/.git/${head#ref: }")"
done
【讨论】:
这是另一种方法:)
git log | grep -o '\w\{8,\}' | head -n 1
【讨论】:
提交哈希
git show -s --format=%H
缩写提交哈希
git show -s --format=%h
-s 标志与--no-patch 相同,代表“抑制差异输出”。
点击here查看更多git show示例。
【讨论】:
这是使用直接从 git 文件读取的 Bash shell 中的单行代码:
(head=($(<.git/HEAD)); cat .git/${head[1]})
您需要在您的 git 根文件夹中运行上述命令。
当您有存储库文件但尚未安装 git 命令时,此方法很有用。
如果不行,在.git/refs/heads文件夹中检查你有什么样的头像。
【讨论】:
我需要一些不同的东西:显示提交的完整 sha1,但如果工作目录不干净,则在末尾附加一个星号。除非我想使用多个命令,否则前面的答案中的选项都不起作用。
这是一个可以做到的班轮:git describe --always --abbrev=0 --match "NOT A TAG" --dirty="*"
结果:f5366ccb21588c0d7a5f7d9fa1d3f85e9f9d1ffe*
说明:描述(使用带注释的标签)当前提交,但仅使用包含“NOT A TAG”的标签。由于标签不能有空格,因此它永远不会匹配标签,并且由于我们想要显示结果--always,因此该命令回退显示提交的完整 (--abbrev=0) sha1,并且如果工作目录是@,它会附加一个星号987654325@.
如果您不想附加星号,这与之前答案中的所有其他命令一样工作:git describe --always --abbrev=0 --match "NOT A TAG"
结果:f5366ccb21588c0d7a5f7d9fa1d3f85e9f9d1ffe
【讨论】:
--match "NOT A TAG" 对我有用。在 git 2.18.0 和 2.7.4 中测试。有什么情况需要这个参数?
git rev-parse HEAD 可以解决问题。
如果您需要在保存实际分支(如果有的话)之后将其存储到结帐时:
cat .git/HEAD
示例输出:
ref: refs/heads/master
解析它:
cat .git/HEAD | sed "s/^.\+ \(.\+\)$/\1/g"
如果您有 Windows,那么您可以考虑使用 wsl.exe:
wsl cat .git/HEAD | wsl sed "s/^.\+ \(.\+\)$/\1/g"
输出:
refs/heads/master
这个值可能会在以后用于 git checkout,但它会指向它的 SHA。要使其通过名称指向实际的当前分支,请执行以下操作:
wsl cat .git/HEAD | wsl sed "s/^.\+ \(.\+\)$/\1/g" | wsl sed "s/^refs\///g" | wsl sed "s/^heads\///g"
输出:
master
【讨论】:
在 git bash 上,只需运行 $ git log -1
你会看到,这些行跟随你的命令。
commit d25c95d88a5e8b7e15ba6c925a1631a5357095db .. (info about your head)
d25c95d88a5e8b7e15ba6c925a1631a5357095db, is your SHA for last commit.
【讨论】: