git name-rev 有什么作用?

Bre*_*min 4 git

根据git name-rev doc

查找适合人类消化的符号名称,以通过 git rev-parse 解析的任何格式给出修订。

但我无法理解这一点。这个命令有什么用?它与git describe命令有什么不同?我认为两者也做同样的事情- 给一个 SHA1 Id,给我们返回最近的引用名称?

tor*_*rek 6

Marek R 的回答是正确的,但有点不完整。

本质上,git name-rev如果需要,提供一个名称加上一些相关表达式,以从名称移动到提交,同时git describe提供一些名称——通常是一个标签名称,但可能是一些其他名称——如果需要,再加上一些额外的字符串,那就是不是特别“相对”:在某些情况下有一个计数,但它不如git name-rev. 如果git describe无法使用原始名称,则会添加g一个缩写的哈希 ID:

$ git describe
v2.19.1-272-gf84b9b09d4
Run Code Online (Sandbox Code Playgroud)

但:

$ git name-rev HEAD
HEAD master
Run Code Online (Sandbox Code Playgroud)

如果我们添加--alltogit describe的参数,git describe确实使用分支名称,但输出不同:

$ git describe --all
heads/master
Run Code Online (Sandbox Code Playgroud)

特别注意它使用的是分支名称,因为如果分支名称和标签名称之间存在冲突(如果也有)refs/tags/mastermaster单独解析将产生与标签相关联的哈希 ID,而不是分支-姓名。

除此之外,如果工作树与提交不匹配,git describe可以添加-dirty,并且 - 从 Git 2.16.0 开始 - 可以生成一个name:pathname字符串来为您提供一个命名特定存储 blob 的表达式:

$ git describe HEAD:Makefile
v2.19.0-237-ge3d4ff037d:Makefile
Run Code Online (Sandbox Code Playgroud)

这不是git name-rev可以管理的东西。

目的不同

[ git name-rev] 有什么用?

我从未真正见过有人自己使用它,但请参见下文。让我们从git describe:的目的开始,它git describe非常常用来生成特定构建的有用描述。因为它默认只使用tags,所以它的输出相对稳定(好吧,如果我们假设 tags 永远不会改变的话)。当git describe说 时v2.19.1-272-gf84b9b09d4,我们知道:

  • 一段时间后提交 v2.19.1
  • 实际提交的哈希 ID 以 f84b9b09d4

并且git describe同一提交的未来输出可能是相同的(尽管如果我们添加新的带注释的标签,它们可能会改变)。可通过v2.19.1..f84b9b09d4以下方式获得 272 次提交的计数:

$ git rev-list --count v2.19.1..f84b9b09d4
272
Run Code Online (Sandbox Code Playgroud)

不会改变。跑步git rev-parse v2.19.1-272-gf84b9b09d4总是会产生f84b9b09d40408cf91bbc500d9f190a7866c3e0f,无论我明天还是下周还是明年再做一次,只要标签v2.19.1保持原样。如果我们使用这个字符串作为构建标识符,我们避免使用分支名称并注意构建是否“脏”,我们可以立即判断我们是否可以在以后轻松地再次重现相同的构建,如果是,如何(即,通过运行git checkout v2.19.1-272-gf84b9b09d4)。

另一方面,当git name-revmastermaster~3什么的时候,不能保证我明天可以回到那个存储库并使用相同的表达式来找到相同的提交。明年,它几乎肯定是错误的。所以git name-rev输出只适用于一小段时间——基本上,直到你移动一些分支名称。

同时,git name-rev有一个git describe不会的技巧:它会解析它的标准输入,寻找似乎是哈希 ID 的东西。当它找到它们时,它会将它们复制到标准输出并添加,前提是散列转换为名称: (expression)

$ X=$(git rev-parse master)
$ echo embedded $X hash | git name-rev --stdin
embedded f84b9b09d40408cf91bbc500d9f190a7866c3e0f (master) hash
$ Y=$(echo $X | sed s/f/0/)
$ echo embedded invalid $Y hash | git name-rev --stdin
embedded invalid 084b9b09d40408cf91bbc500d9f190a7866c3e0f hash
Run Code Online (Sandbox Code Playgroud)

这意味着您可以如文档中所示,运行git log | git name-rev并让所有这些提交哈希成为装饰哈希。但是,散列必须是完整的散列。相比:

$ git log --oneline -n 10 | git name-rev --stdin
f84b9b09d4 Sync with 2.19.1
cae598d998 Git 2.19.1
1958ad504b Sync with 2.18.1
268fbcd172 Git 2.18.1
44f87dac99 Sync with 2.17.2
6e9e91e9ca Git 2.17.2
1a7fd1fb29 fsck: detect submodule paths starting with dash
a124133e1e fsck: detect submodule urls starting with dash
e43aab778c Sync with 2.16.5
27d05d1a1a Git 2.16.5
Run Code Online (Sandbox Code Playgroud)

和:

$ git log --pretty=tformat:'%H %s' -n 10 | git name-rev --stdin
f84b9b09d40408cf91bbc500d9f190a7866c3e0f (master) Sync with 2.19.1
cae598d9980661a978e2df4fb338518f7bf09572 (tags/v2.19.1^0) Git 2.19.1
1958ad504befa6a09c475cc8ab9de43b359de137 (tags/v2.19.1~1) Sync with 2.18.1
268fbcd172cdb306e8a3e7143cc16677c963d6cd (tags/v2.18.1^0) Git 2.18.1
44f87dac99574a8073ffb1ba8b10bd4d3945f61b (tags/v2.18.1~1) Sync with 2.17.2
6e9e91e9cae74cd7feb9300563d40361b2b17dd2 (tags/v2.17.2^0) Git 2.17.2
1a7fd1fb2998002da6e9ff2ee46e1bdd25ee8404 (tags/v2.17.2~1) fsck: detect submodule paths starting with dash
a124133e1e6ab5c7a9fef6d0e6bcb084e3455b46 (tags/v2.17.2~2) fsck: detect submodule urls starting with dash
e43aab778c72250e11eb00e31dc6be90072a1637 (tags/v2.17.2~3) Sync with 2.16.5
27d05d1a1a62273aa3749f4d0ab8a126ef11ff66 (tags/v2.16.5^0) Git 2.16.5
Run Code Online (Sandbox Code Playgroud)

底线:使用最适合您特定目的的那个。哪一个取决于你的目的是什么。