按:写作本文时查阅了一些资料,也做了一些实验,但有好些只是个人的理解,可能有误。
git 的 tag 分两种:
官方的说法如下:
Tag objects (created with -a, -s, or -u) are called “annotated” tags; they contain a creation date, the tagger name and e-mail, a tagging message, and an optional GnuPG signature. Whereas a “lightweight” tag is simply a name for an object (usually a commit object).
Annotated tags are meant for release while lightweight tags are meant for private or temporary object labels. For this reason, some git commands for naming objects (like git describe) will ignore lightweight tags by default.
git tag test-only-lightweight
git tag -a "test-only-annotated" -m "test tag: annotated"
查看本地的全部 tag
$ git tag
# or
$ git tag --list
按 tag 名查找:
$ git tag --list "test-only*"
test-only-annotated
test-only-lightweight
上面也可以变通地使用命令:
$ git tag --list | grep "test-only"
查看 tag 的元信息:
$ git show test-only-annotated
tag test-only-annotated
Tagger: Cao Yi <iridiumcao@gmail.com>
Date: Tue Nov 7 10:35:56 2023 +0800
test tag: annotated
(以上是该 tag 的相关信息展示,后面向接的就是 commit 的常规信息,这里省略)
但 git show test-only-lightweight
可以看出:没有和该 tag 有关的任何信息,这看起来符合前面提到的——轻量 tag 只是个别名而已。
$ git push origin refs/tags/test-only-lightweight
$ git push origin refs/tags/test-only-annotated
这里我用了完整的 tag 路径 refs/tags/name
,是为了避免 tag 和 branch 同名时用短名无法推送的问题。如果没有同名的情况,可以使用下面的简便方式:
$ git push origin test-only-lightweight
$ git push origin test-only-annotated
前面使用 git tag
可以查看本地的 tag,远程我们使用下面的方式:
$ git ls-remote --tags ssh://git@192.168.5.67:2222/hello/world.git | grep "test-only"
如果执行命令的当前目录就是这个远程库对应的本地库,则远程库的地址可以省略,如下:
$ git ls-remote --tags | grep "test-only"
From ssh://git@192.168.5.67:2222/hello/world.git
65aef7ff2efdfe73253238b388513da62ad8060b refs/tags/test-only-annotated
85084db2c79b1a18f5b3e836cc5656d97fa098c0 refs/tags/test-only-annotated^{}
85084db2c79b1a18f5b3e836cc5656d97fa098c0 refs/tags/test-only-lightweight
注意,标记 tag 有两条记录,其中以 ^{}
结尾的记录的 ID 和轻量 tag 是一样的,说明标记 tag 在 git 中实际上由两条记录构成:
^{}
结尾的记录,和轻量 tag 等同,但无法通过 git tag
列出,默认对用户隐藏,不过可以通过 git ls-remote --tags
列出。我们通过观察 tag 在远程有几条记录来确认它是轻量 tag 还是标记 tag.
可以使用完整的路径删除:
$ git push origin --delete refs/tags/test-only-lightweight
$ git push origin --delete refs/tags/test-only-annotated
当 tag 和 branch 名称不会混淆时,可以用简便的方式:
$ git push origin --delete test-only-lightweight
$ git push origin --delete test-only-annotated
注意,删除标记 tag 时,不要使用带 ^{}
的标签名,下面一条错误的示例:
$ git push origin --delete refs/tags/hello^{}
fatal: invalid refspec ':refs/tags/hello^{}'
可以分别删除,也可以一起删除
$ git tag --delete test-only-annotated test-only-lightweight