检查远程git标签是否已更改

时间:2018-11-06 00:57:20

标签: git

我有一个本地git存储库,其中的工作树已同步到特定标签。我想看看原始仓库是否已尽可能有效地更改了该标签,如果有,请创建一个新的工作树。

我当时使用git rev-list -n1 tagname来查看我的本地标签的哈希,并使用git ls-remote -q origin refs/tags/tagname^{}来查看遥控器的标签。

这适用于我测试过的所有情况,但现在我发现在某些情况下^{}使其返回空值。遥控器具有标签,但没有^{}形式。

例如

$ git ls-remote --tags
From https://github.com/kubernetes/git-sync
8bb6ccf948dbdfdb8a2d88d13db96e272e3573b8    refs/tags/v2.0.0
15ba74321c4ce41aa935271105e999011afc2d01    refs/tags/v2.0.1
7984f521cf97a8aeffffa5da490dfb5410c6273b    refs/tags/v2.0.2

$ git ls-remote -q origin refs/tags/v2.0.0^{}

我在搞什么?如何处理有^ {}且需要取消引用的案例以及没有被取消引用的案例?

必须对此有一个简单的答案。

1 个答案:

答案 0 :(得分:1)

^{}实际上是gitrevisions syntax的一部分。它告诉Git 去皮标签:查找(可能是带注释的)标签指向的对象,而不是查找带注释的标签本身。

  

我正在使用git rev-list -n1 tagname来查看我的本地标签的哈希值...

这是问题的真正根源:git rev-list列出了 commits ,但是标记引用可能不指向提交。当标签引用指向带注释的标签时,您可能应该获取带注释的标签对象的哈希ID。为此,请使用git rev-parse而不是git rev-list

$ git rev-parse v2.19.1
0d3c37ddaccbb48809fdd3810ebb3f2bc961973c
$ git rev-parse v2.19.1^{}
cae598d9980661a978e2df4fb338518f7bf09572
$ git rev-list -n1 v2.19.1
cae598d9980661a978e2df4fb338518f7bf09572

(这里v2.19.1是Git的Git存储库中的带注释的标记)。请注意,标记的带注释标记如何导致提交,因此具有剥离选项的git rev-parsegit rev-list都找到了相同的提交。 1

使用git ls-remote时,如果注释了远程标记,则远程同时传递标记的对象哈希,后缀为^{},即对象的哈希ID。 2 如果遥控器的标签没有 注释,则git ls-remote会传递该标签指向的对象的哈希ID。 (标记直接指向那里,而不是通过带注释的标记对象。)

标签永远都不能更改,例如,绝对不能从带注释的标签变为未注释的标签,反之亦然,也不要更改基础对象。但是,如果标签进行更改,则哈希ID会即使基础标记的对象哈希ID相同,也应进行更改。但是在这种情况下,您可能还是想更新本地标签。


1 如果标记指向其他对象类型(树或Blob),则git rev-list不会执行任何操作,而git rev-parse将成功执行;可以使用^{commit}来使git rev-parse失败:

$ git rev-list -n1 xxx
$ git rev-parse xxx
596ad6ec669abd0c6ad6034cd3b219fb6ea3ab1d
$ git cat-file -p xxx
object b22571e0489ee9a664885594316a7ccfc9186360
type blob
[snip]
$ git rev-parse xxx^{}
b22571e0489ee9a664885594316a7ccfc9186360
$ git rev-parse xxx^{commit}
error: xxx^{commit}: expected commit type, but the object dereferences to blob type
xxx^{commit}
error: xxx^{commit}: expected commit type, but the object dereferences to blob type
fatal: ambiguous argument 'xxx^{commit}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

2 请注意,如果带注释的标记对象指向另一个带注释的标记对象或指向一系列带注释的标记对象,则^{}解析过程仍会找到最终对象,无论是。因此,最好谈论“已解决的对象”或“被剥皮的值”,或者您喜欢描述发现非标签对象的过程的任何短语。

(对非注释标签或任何其他有效的哈希ID进行剥离是无操作的,但是允许的。您可以根据需要添加任意数量的^{}后缀,尽管只有第一个可以执行任何操作,即使如此,仅当对象是带注释的标签时也是如此。)