我想保留(目前)将Git变更集链接到存储在TFS中的工作项的能力。
我已经编写了一个工具(使用git中的钩子),在该工具中,我可以将WorkitemIdentifiers注入git变更集的消息中。
但是,我还希望将git commit(散列)的标识符存储到自定义tfs工作项字段中。通过这种方式,我可以检查TFS中的工作项,并查看哪些Git变更集与该工作项关联。
如何轻松地从Git的当前提交中检索哈希?
例如,要将任意扩展对象引用转换为sha-1,只需使用git rev parse
或
1
| git rev-parse --verify 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返回哈希的简短版本,以防有人好奇。
- 除了thane所说的,您还可以向--short添加特定的长度,例如--short=12,以从散列中获得特定的位数。
- @tysonphalp:--short=N大约是数字的最小数目;如果缩短一个数字,git会使用更大的数字数目,而另一个则无法区分。例如,git rev-parse --short=2 HEAD或git log --oneline --abbrev=2。
- 除了Thane、Tyson和Jakub所说的内容之外,您还可以打印完整的哈希,但要用git rev-parse HEAD | GREP_COLORS='ms=34;1' grep $(git rev-parse --short=0 HEAD)突出显示识别commit blue所需的十六进制数。
- 巧妙的技巧,扎兹。它似乎不适用于我的Mac电脑上的grep,但我用ack替代了类似的效果!
- @扎兹也不适合我,但简单地说,埃多克斯(10)就行了。
- 有没有一种方法可以做到这一点,但以每个目录为基础?例如,假设我想要一个特定目录的最新哈希。我需要做一个git log 并解析它来获取散列值吗?
- @亚伦:大致来说是的,你需要运行git log -- ;但是你可以配置git日志,这样它只返回hash。
- 加上@thanebrimhall所说的内容,您可以使用git rev-parse ca003ae从哈希的短版本中获得完整的sha-1引用。
- 如果你有一个名为"head"的标签,这个方法有效吗?>)
- @edrandall:git rev-parse的主要目的是解析参数并返回修订,所以--short表示修订的sha-1被缩短。git log返回更多信息,包括修订版的sha-1,可以用--abbrev或--abbrev-commit缩写。
- git rev-parse HEAD | pbcopy非常适合在Mac上快速粘贴剪贴板。
- 酷!我甚至把它添加到别名:git config --global alias.sha 'rev-parse HEAD'。现在我可以简单地使用git sha。
- 这是答案并不总是正确的!如果头部不在您的签出提交处(分离的头部),您得到的返回是不正确的。只有git status才会提供正确的提交哈希。
如果只需要缩短的哈希:
1
| git log --pretty=format:'%h' -n 1 |
。
此外,使用%h是获得长哈希的另一种方法。
- 或者,在上面的rev-parse命令中加上--short似乎可以工作。
- 我认为git log是瓷器,git rev-parse是管道。
- 此方法的一个好处是,它将返回哈希的短版本,并根据较大的repo发生的哈希冲突调整适当的长度。至少在Git的最新版本中。
- 这是一种错误的/不正确的方法,因为如果您有一个分离的头,这个方法会给您错误的散列值。例如,如果当前提交是12ab34…之前的承诺是33AA44…如果我执行"git checkout 33aa44",然后运行您的命令,我仍然可以返回12ab34…尽管我的头实际上指向33AA44…
- @我没有经历过你描述的那种行为;埃多克斯1〔28〕给了我埃多克斯1〔29〕。您使用的是什么版本的Git?
另一个,使用git日志:
1
| git log -1 --format="%H" |
它与@outofculture非常相似,不过有点短。
- 结果不是单引用的。
- 这是正确的答案,因为即使您签出一个特定的commit而不是HEAD,它也可以工作。
要获得完整的sha:
1 2
| $ git rev-parse HEAD
cbf1b9a1be984a9f61b79a05f23b19f66d533537 |
号
要获得缩短的版本:
1 2
| $ git rev-parse --short HEAD
cbf1b9a |
- 如果需要两个gitcommit散列,例如一个来自您当前工作的branch散列和一个masterbranch散列,如果您需要mastercommit散列,您也可以使用git rev-parse FETCH_HEAD散列,如果您需要将merge引入当前branch的mastercommit散列。例如,如果您有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用于您可能拥有的任何脚本。
为了完整性,因为还没有人提出建议。.git/refs/heads/master是一个只包含一行的文件:master上最新提交的哈希。所以你可以从那里读出来。
或者,作为命令:
1
| cat .git/refs/heads/master |
更新:
注意,Git现在支持在pack-ref文件中存储一些head-refs,而不是作为/refs/heads/文件夹中的文件。https://www.kernel.org/pub/software/scm/git/docs/git-pack-refs.html网站
- 这假设当前分支是master,这不一定是正确的。
- 的确。这就是为什么我明确地说这是为了master。
- 有.git/HEAD,它是一个文件,其中包含1行与head的sha1。我想这就是你的意思。
- .git/HEAD通常指向一个参考点,如果你在那里有一个sha1,你就处于分离头模式。
- 与其他方法相比,这并不是很强大,特别是因为它假定存在一个.git子目录,而这种情况并不一定如此。参见git init手册页中的--separate-git-dir标志。
- +1因为有时您不希望安装git可执行文件(例如在Dockerfile中)
- 用于查找分支.git/refs/heads/ 的sha-hash
- +1-和-如果您不需要拉/重定/合并,只想获取hash post fetch cat .git/refs/remotes/origin/master。
- cat.git/$(cat.git/head awk'打印$2;')应该工作了吗?
也总是有git describe。默认情况下它会给你--
1 2
| john@eleanor:/dev/shm/mpd/ncmpc/pkg (master)$ git describe --always
release-0.19-11-g7a68a75 |
- git-describe返回提交后可访问的第一个标记。这有助于我获得sha吗?
- 我喜欢git describe --long --dirty --abbrev=10 --tags,它会给我一些像7.2.0.Final-447-g65bf4ef2d4的东西,在7.2.0之后提交447个。当前头部的全球sha-1的最后一个标签和前10个摘要是"65bf4ef2d4"。这对于版本字符串非常好。使用--long,它将始终添加计数(-0-)和哈希,即使标记恰好匹配。
- 如果不存在标记,那么git describe --always将"以回退方式显示唯一缩写的提交对象"
提交哈希
缩写的提交哈希
单击此处查看更多git show示例。
使用git rev-list --max-count=1 HEAD。
- Git Rev List是关于生成提交对象列表的;它是Git Rev Parse,用于将对象名(例如head)转换为sha-1
如果需要在脚本期间将哈希存储在变量中,则可以使用
1
| last_commit=$(git rev-parse HEAD) |
。
或者,如果只需要前10个字符(如github.com)
1
| last_commit=$(git rev-parse HEAD | cut -c1-10) |
。
- git rev-parse也有--short或--short=number参数;不需要使用管道和cut参数。
我知道的最简洁的方法是:
。
如果需要哈希的特定位数,可以添加:
- 虽然这在技术上可行,但git show是一个所谓的瓷质命令(即面向用户的命令),因此不应在脚本中使用,因为其输出可能会发生变化。应使用上述答案(git rev-parse --short HEAD)。
- @JM3倒过来了。""瓷质"命令具有稳定的脚本输出。在git help show中搜索porcelain。
- @约翰·多赫,你是对的,我的错。
- @Johntyree这是一个令人困惑的主题,但JM3是对的:瓷质命令不是要被解析的,而是要让人可读。如果您需要在脚本中使用一个瓷质命令,并且希望有一个稳定的格式,那么有时(例如,使用git状态、push和blank)会有一个这样的选项。不幸的是,这个选项被称为--porcelain,这就是为什么这令人困惑的原因。你可以在VONC的这个伟大的答案中找到细节。
- 亲爱的上帝,谁决定命名这个选择-瓷器我想找到他们和…哦,等等,我需要用Git永远找不到他们
也许你需要一个别名,这样你就不必记住所有漂亮的细节。完成以下步骤之一后,您将能够简单地键入:
1 2
| $ git lastcommit
49c03fc679ab11534e1b4b35687b1225c365c630 |
号
跟进已接受的答案,有两种设置方法:
1)通过编辑全局配置(我的原始答案),教Git明确的方法:
1 2 3 4 5 6 7
| # open the git config editor
$ git config --global --edit
# in the alias section, add
...
[alias]
lastcommit = rev-parse HEAD
... |
号
2)或者如果你喜欢教Git一个捷径,就像最近Adrien评论的那样:
1
| $ git config --global alias.lastcommit"rev-parse HEAD" |
号
从这里开始,使用git lastcommit显示最后一次提交的哈希。
- Adrien de Sentenac注意到,您不必手动编辑git配置文件,只需执行以下操作:git config --global alias.lastcommit"rev-parse HEAD"。
- @Adrien谢谢,相应更新。
如果你想要超级黑客的方式:
1
| cat .git/`cat .git/HEAD | cut -d \ -f 2` |
号
基本上,git以.git/head的形式存储head的位置,格式为ref: {path from .git}。这个命令读取这些信息,切掉"ref:",并读取它指向的任何文件。
当然,这在分离头模式下会失败,因为head不是"ref:…",而是散列本身-但是你知道,我认为你不希望在bash-one中有那么多的聪明。如果你不认为分号作弊,尽管…
1
| HASH="ref: HEAD"; while [[ $HASH == ref\:* ]]; do HASH="$(cat".git/$(echo $HASH | cut -d \ -f 2)")"; done; echo $HASH |
号
- 不需要安装git,我喜欢。(我的Docker构建映像没有git)
- 也很有用,因为您可以从git repo外部轻松地运行它。
- 我把这个形式化为本地机器的脚本。然后,我想,嘿:我所做的实现非常简单,它说明了如何解决一个不相关的问题(在没有外部程序的原始posix shell脚本中解析参数),但是足够复杂,可以提供一点变化,并利用sh的大部分功能。半小时后的文档评论,这里有一个要点:gist.github.com/fordi/29b8d6d1ef1662b306bfc2bd99151b07
- 看看它,我做了一个更广泛的版本来检测git和svn,并获取git hash/svn版本。这次不是一个干净的字符串,但很容易对命令行进行解析,并可用作版本标记:gist.github.com/fordi/8f1828efd820181f2430b292670b14e
我需要一些更不同的东西:显示提交的完整sha1,但是如果工作目录不干净,在末尾附加一个星号。除非我想使用多个命令,否则前面答案中的所有选项都不起作用。
这是一个可以做到:git describe --always --abbrev=0 --match"NOT A TAG" --dirty="*"。结果:f5366ccb21588c0d7a5f7d9fa1d3f85e9f9d1ffe*。
说明:描述(使用带注释的标记)当前提交,但只使用包含"not a tag"的标记。由于标记不能有空格,所以这永远不匹配标记,而且由于我们想要显示结果--always,所以命令会返回显示commit的完整(--abbrev=0sha1,如果工作目录是--dirty则会附加一个星号。
如果不想附加星号,这与前面答案中的所有其他命令一样工作:埃多克斯1〔5〕结果:f5366ccb21588c0d7a5f7d9fa1d3f85e9f9d1ffe。
- 谢谢,只是绊倒了它,它让我少了一个或另一个回声。
- 没有江户一号〔19〕对我有用。在Git 2.18.0和2.7.4中测试。在任何情况下都需要这个论点吗?
- @托马斯,如果您在当前提交的历史记录中的任何地方都有一个带注释的标记,那么它将不起作用。伪标记确保describe命令不使用标记来描述提交,
1
| git show-ref --head --hash head |
。
如果你想加快速度,迪斯坦提到的方法
1
| cat .git/refs/heads/<branch-name> |
号
比这里列出的任何其他方法都快得多。
- 在我看来,show-ref是脚本编写的最佳选择,因为它是一个管道命令,因此保证(或至少非常可能)在将来的版本中保持稳定:其他答案使用rev-parse、show、describe或log,它们都是瓷命令。在速度不重要的情况下,show-ref手册中的注释适用:"鼓励使用此实用程序,以便直接访问.git目录下的文件。"
下面是bash shell中使用从git文件直接读取的一个行程序:
1
| (head=($(<.git/HEAD)); cat .git/${head[1]}) |
您需要在git根文件夹中运行上述命令。
当您有存储库文件,但尚未安装git命令时,此方法非常有用。
如果不起作用,请查看.git/refs/heads文件夹,您有什么样的头。
在home dir in file".gitconfig"中添加以下内容
1 2
| [alias]
sha = rev-parse HEAD |
号
然后您将有一个更容易记住的命令:
1 2
| $ git sha
59fbfdbadb43ad0b6154c982c997041e9e53b600 |
号
以下是另一种方法:)
1
| git log | grep -o '\w\{8,\}' | head -n 1 |
号
下面是另一个直接访问实现:
1 2 3 4
| head="$(cat".git/HEAD")"
while ["$head" !="${head#ref: }" ]; do
head="$(cat".git/${head#ref: }")"
done |
。
这也适用于HTTP,它对本地包存档很有用(我知道:对于公共网站,建议不要使.git目录可访问):
1 2 3 4
| head="$(curl -s"$baseurl/.git/HEAD")"
while ["$head" !="${head#ref: }" ]; do
head="$(curl -s"$baseurl/.git/${head#ref: }")"
done |
号
以下是使用提交哈希对我有效的步骤:
登录您的Git Hub链接,例如:https://github..com。
登录后,在"搜索或跳转到…"文本框中输入为:
根据您的需要,在"所有Github企业"或"在此组织中"之间进行选择
按Enter键。