简体中文 ▾ 主题 ▾ 最新版本 ▾ git-tag 最后更新于 2.52.0

名称

git-tag - 创建、列出、删除或验证标签

概要

git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]
	[(--trailer <token>[(=|:)<value>])…​]
	<tagname> [<commit> | <object>]
git tag -d <tagname>…​
git tag [-n[<num>]] -l [--contains <commit>] [--no-contains <commit>]
	[--points-at <object>] [--column[=<options>] | --no-column]
	[--create-reflog] [--sort=<key>] [--format=<format>]
	[--merged <commit>] [--no-merged <commit>] [<pattern>…​]
git tag -v [--format=<format>] <tagname>…​

描述

refs/tags/ 中添加一个标签引用,除非使用了 -d/-l/-v 参数来删除、列出或验证标签。

除非使用了 -f 参数,否则指定的标签名必须尚不存在。

如果传递了 -a-s-u <key-id> 其中之一,该命令将创建一个“标签(tag)”对象,并需要一条标签消息。除非给出了 -m <msg>-F <file>,否则会启动一个编辑器供用户输入标签消息。

如果给出了 -m <msg>-F <file>--trailer <token>[=<value>],但缺失 -a-s-u <key-id>,则隐含了 -a 参数。

否则,将创建一个直接指向给定对象(即轻量级标签)的标签引用。

当使用 -s-u <key-id> 时,将创建一个经过加密签名的标签对象。签名后端(GPG、X.509、SSH 等)由 gpg.format 配置变量控制,默认为 OpenPGP。当未使用 -u <key-id> 时,将使用当前用户的提交者身份来查找签名密钥。配置变量 gpg.program 用于指定自定义签名二进制文件。

标签对象(使用 -a-s-u 创建)被称为“附注(annotated)”标签;它们包含创建日期、打标签者的姓名和电子邮件、一条标签消息以及可选的加密签名。而“轻量(lightweight)”标签仅仅是一个对象的名称(通常是一个提交对象)。

附注标签通常用于发布,而轻量级标签则用于私有或临时的对象标识。因此,一些用于命名对象的 Git 命令(如 git describe)默认会忽略轻量级标签。

选项

-a
--annotate

创建一个未签名的附注标签对象

-s
--sign

使用默认签名密钥创建一个经过加密签名的标签。所使用的签名后端取决于 gpg.format 配置变量。默认密钥由后端决定。对于 GPG,它基于提交者的电子邮件地址;对于 SSH,它可能是一个特定的密钥文件或代理身份。参见 git-config[1]

--no-sign

覆盖强制对每一个标签进行签名的 tag.gpgSign 配置变量。

-u <key-id>
--local-user=<key-id>

使用给定的密钥创建一个经过加密签名的标签。<key-id> 的格式和所使用的后端取决于 gpg.format 配置变量。参见 git-config[1]

-f
--force

替换具有给定名称的现有标签(而不是报错失败)

-d
--delete

删除具有给定名称的现有标签。

-v
--verify

验证给定标签的加密签名。

-n<num>

<num> 指定在使用 -l 时打印附注(如果有)的行数。隐含 --list

默认不打印任何附注行。如果 -n 后面没有给出数字,则只打印第一行。如果标签不是附注标签,则显示提交消息。

-l
--list

列出标签。配合可选的 <pattern>...(例如 git tag --list 'v-*'),仅列出匹配模式的标签。

不带参数运行 git tag 也会列出所有标签。该模式是 shell 通配符(即使用 fnmatch(3) 进行匹配)。可以给出多个模式;如果其中任何一个匹配,则显示该标签。

如果提供了任何其他类似列表的选项(如 --contains),则会隐式提供此选项。详情请参见这些选项各自的文档。

--sort=<key>

基于给定的键进行排序。前缀 - 表示按值的降序排序。您可以多次使用 --sort=<key> 选项,在这种情况下,最后一个 <key> 成为主键。还支持 "version:refname" 或 "v:refname"(标签名称被视为版本号)。"version:refname" 排序顺序也受 "versionsort.suffix" 配置变量的影响。支持的键与 git for-each-ref 中的键相同。如果存在 tag.sort 变量,则排序顺序默认为该变量配置的值,否则默认为词典顺序。参见 git-config[1]

--color[=<when>]

尊重 --format 选项中指定的任何颜色。<when> 字段必须是 alwaysneverauto 之一(如果缺失 <when>,其行为等同于 always)。

-i
--ignore-case

对标签的排序和过滤不区分大小写。

--omit-empty

在格式化引用中,如果格式扩展为空字符串,则不在其后打印换行符。

--column[=<options>]
--no-column

以列的形式显示标签列表。有关选项语法,请参见配置变量 column.tag。不带选项的 --column--no-column 分别等同于 alwaysnever

此选项仅在列出不带附注行的标签时适用。

--contains [<commit>]

仅列出包含 <commit> 的标签(如果未指定,则为 HEAD)。隐含 --list

--no-contains [<commit>]

仅列出不包含 <commit> 的标签(如果未指定,则为 HEAD)。隐含 --list

--merged [<commit>]

仅列出其提交可从 <commit> 到达的标签(如果未指定,则为 HEAD)。

--no-merged [<commit>]

仅列出其提交不可从 <commit> 到达的标签(如果未指定,则为 HEAD)。

--points-at [<object>]

仅列出指向 <object> 的标签(如果未指定,则为 HEAD)。隐含 --list

-m <msg>
--message=<msg>

使用 <msg> 作为标签消息(而不是提示输入)。如果给出了多个 -m 选项,它们的值将连接为独立的段落。如果没有给出 -a-s-u <key-id>,则隐含 -a

-F <file>
--file=<file>

<file> 中获取标签消息。使用 - 从标准输入读取消息。如果没有给出 -a-s-u <key-id>,则隐含 -a

--trailer <token>[(=|:)<value>]

指定应作为尾注(trailer)应用的 (<token>, <value>) 对。(例如 git tag --trailer "Custom-Key: value" 将在标签消息中添加 "Custom-Key" 尾注。)trailer.* 配置变量(git-interpret-trailers[1])可用于定义是否忽略重复的尾注、每个尾注在尾注序列中的出现位置以及其他细节。在 git tag --list 中,可以使用 --format="%(trailers)" 占位符提取尾注。

-e
--edit

允许进一步编辑使用 -F 从文件获取或使用 -m 从命令行获取的消息。

--cleanup=<mode>

设置标签消息的清理方式。<mode> 可以是 verbatim(逐字)、whitespace(空白)和 strip(剥离)之一。strip 模式是默认值。verbatim 模式完全不改变消息,whitespace 仅删除首尾空白行,而 strip 则同时删除空白和注释。

--create-reflog

为标签创建一个引用日志(reflog)。要全局启用标签的引用日志,请参阅 git-config[1] 中的 core.logAllRefUpdates。否定形式 --no-create-reflog 仅覆盖之前的 --create-reflog,目前不会否定 core.logAllRefUpdates 的设置。

--format=<format>

一个字符串,用于从正在显示的标签引用及其指向的对象中插值 %(fieldname)。格式与 git-for-each-ref[1] 相同。未指定时,默认为 %(refname:strip=2)

<tagname>

要创建、删除或描述的标签名称。新标签名称必须通过 git-check-ref-format[1] 定义的所有检查。其中一些检查可能会限制标签名称中允许使用的字符。

<commit>
<object>

新标签将引用的对象,通常是一个提交。默认为 HEAD

配置

默认情况下,处于“以默认身份签名”模式(-s)下的 git tag 将使用您的提交者身份(格式为 姓名 <your@email.address>)来查找密钥。如果您想使用不同的默认密钥,可以在仓库配置中指定如下:

[user]
    signingKey = <key-id>

签名后端可以通过 gpg.format 配置变量来选择,该变量默认为 openpgp。有关其他受支持格式的列表,请参阅 git-config[1]

每个签名后端使用的程序路径可以通过 gpg.<format>.program 配置变量指定。对于 openpgp 后端,gpg.program 可以作为 gpg.openpgp.program 的同义词使用。详情请参阅 git-config[1]

pager.tag 仅在列出标签时(即使用或隐含 -l 时)被尊重。默认是使用分页器。

有关更多详细信息和其他配置变量,请参阅 git-config[1]

讨论

关于重新打标签

如果您在一个错误的提交上打了标签,并且想要重新打标签,该怎么办?

如果您从未推送过任何内容,只需重新打标签即可。使用 -f 来替换旧标签。这就完成了。

但是如果您已经推送了内容(或者其他人可以直接读取您的仓库),那么其他人就已经看到了旧标签。在这种情况下,您可以做以下两件事之一:

  1. 理智的做法。承认您搞砸了,并使用一个不同的名称。其他人已经看到了一个标签名称,如果您保持相同的名称,可能会出现两个人都拥有“版本 X”,但他们实际上拥有的是*不同*的“X”的情况。所以只需将其称为“X.1”并结束即可。

  2. 疯狂的做法。您确实也想把新版本称为“X”,*尽管*其他人已经看到了旧版本。所以只需再次使用 git tag -f,就像您还没有发布旧版本一样。

然而,Git **不会**(也不应该)在用户背后更改标签。因此,如果有人已经获取了旧标签,在您的树上执行 git pull 不应该直接覆盖旧标签。

如果有人从您那里获得了一个发布标签,您不能通过更新自己的标签来简单地为他们更改标签。这是一个重大的安全问题,因为人们必须能够信任他们的标签名称。如果您真的想做这种疯狂的事情,您需要坦白承认,并告诉大家您搞砸了。您可以通过发布一份非常公开的声明来做到这一点,例如:

Ok, I messed up, and I pushed out an earlier version tagged as X. I
then fixed something, and retagged the *fixed* tree as X again.

If you got the wrong tag, and want the new one, please delete
the old one and fetch the new one by doing:

	git tag -d X
	git fetch origin tag X

to get my updated tag.

You can test which tag you have by doing

	git rev-parse X

which should return 0123456789abcdef.. if you have the new version.

Sorry for the inconvenience.

这看起来是否有点复杂?它**理应**如此。自动“修复”它绝对是不正确的。人们需要知道他们的标签可能已被更改。

关于自动跟进

如果您正在关注其他人的树,您很可能正在使用远程跟踪分支(例如 refs/remotes/origin/master)。您通常想要另一端的标签。

另一方面,如果您执行获取(fetch)是因为您想要从某人那里进行一次性合并,通常您不希望从那里获取标签。这种情况在接近顶层的人员中更为常见,但不仅限于他们。普通人在互相拉取时,不一定希望自动获取对方的私人锚点标签。

通常,邮件列表上的“请拉取(please pull)”消息只提供两条信息:仓库 URL 和分支名称;这旨在方便剪切并粘贴到 git fetch 命令行末尾:

Linus, please pull from

	git://git..../proj.git master

to get the following updates...

变为

$ git pull git://git..../proj.git master

在这种情况下,您不希望自动跟进对方的标签。

Git 的一个重要方面是其分布式特性,这很大程度上意味着系统中没有固有的“上游”或“下游”。表面上看,上述例子似乎表明标签命名空间归上层人士所有,标签只能向下流动,但事实并非如此。它只表明使用模式决定了谁对谁的标签感兴趣。

一次性拉取是一个信号,表明提交历史现在正跨越一个群体(例如“主要对内核网络部分感兴趣的人”,他们可能有自己的一套标签,如“这是网络组为 2.6.21 版本提议供大众消费的第三个发布候选版本”)与另一个群体(例如“整合各种子系统改进的人”)之间的边界。后者通常对前一组内部使用的详细标签不感兴趣(这就是“内部”的含义)。这就是为什么在这种情况下最好不要自动跟进标签。

很可能在网络人员之间,他们可能想要交换组内内部的标签,但在该工作流中,他们很可能通过拥有远程跟踪分支来跟踪彼此的进展。同样,自动跟进此类标签的启发式方法是一件好事。

关于回溯标签日期

如果您从另一个 VCS 导入了一些更改,并希望为您作品的主要版本添加标签,那么能够指定嵌入在标签对象内部的日期是很有用的;标签对象中的此类数据会影响(例如)gitweb 界面中标签的排序。

要设置未来标签对象中使用的日期,请设置环境变量 GIT_COMMITTER_DATE(请参阅稍后关于可能值的讨论;最常见的形式是 "YYYY-MM-DD HH:MM")。

例如

$ GIT_COMMITTER_DATE="2006-10-02 10:31" git tag -s v1.0.1

日期格式

GIT_AUTHOR_DATEGIT_COMMITTER_DATE 环境变量支持以下日期格式:

Git 内部格式

格式为 <unix-timestamp> <time-zone-offset>,其中 <unix-timestamp> 是自 UNIX 纪元以来的秒数。<time-zone-offset> 是相对于 UTC 的正或负偏移量。例如,CET(比 UTC 早 1 小时)是 +0100

RFC 2822

RFC 2822 所描述的标准日期格式,例如 Thu, 07 Apr 2005 22:13:13 +0200

ISO 8601

由 ISO 8601 标准指定的日期和时间,例如 2005-04-07T22:13:13。解析器也接受用空格代替 T 字符。小数秒将被忽略,例如 2005-04-07T22:13:13.019 将被视为 2005-04-07T22:13:13

注意
此外,日期部分支持以下格式:YYYY.MM.DDMM/DD/YYYYDD.MM.YYYY

文件

$GIT_DIR/TAG_EDITMSG

此文件包含正在进行的附注标签的消息。如果 git tag 在创建附注标签之前因错误退出,则用户在编辑器会话中提供的标签消息将保存在此文件中,但可能会被下一次调用 git tag 时覆盖。

配置

本节中以下所有内容均从 git-config[1] 文档中选择性地包含。内容与彼处相同:

tag.forceSignAnnotated

一个布尔值,指定创建的附注标签是否应经过 GPG 签名。如果在命令行上指定了 --annotate,则其优先级高于此选项。

tag.sort

此变量控制由 git-tag 显示时标签的排序顺序。在未提供 --sort=<value> 选项的情况下,将使用此变量的值作为默认值。

tag.gpgSign

一个布尔值,指定是否所有标签都应经过 GPG 签名。在自动化脚本中使用此选项可能会导致大量标签被签名。因此,使用代理(agent)以避免多次输入 GPG 密码会很方便。请注意,此选项不会影响由 -u <keyid>--local-user=<keyid> 选项启用的标签签名行为。

注意事项

当组合多个 --contains--no-contains 过滤器时,仅显示至少包含一个 --contains 提交且不包含任何 --no-contains 提交的引用。

当组合多个 --merged--no-merged 过滤器时,仅显示至少一个 --merged 提交可达且不被任何 --no-merged 提交可达的引用。

GIT

Git[1] 套件的一部分