## Name

git-tag - 创建，列出，删除或验证用 GPG 签名的标签对象

## 概要

    git tag [-a | -s | -u <keyid>] [-f] [-m <msg> | -F <file>]        <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>]        [--[no-]merged [<commit>]] [<pattern>…]git tag -v [--format=<format>] <tagname>…

## 描述

除非`-d/-l/-v`给予删除，列出或验证标签，否则添加标签引用`refs/tags/。`

除非`-f`给出，否则指定的标记不能存在。

如果`-a`，`-s`或`-u <keyid>`其中之一通过，该命令将创建一个`tag`对象，并且需要标记消息。除非`-m <msg>`或者`-F <file>`给出，否则启动编辑器以供用户输入标签消息。

如果`-m <msg>`或者`-F <file>`被给予，并且`-a`，`-s`和`-u <keyid>`不存在，`-a`则暗示。

否则，只会创建提交对象的SHA-1对象名称的标记引用（即轻量级标记）。

GnuPG 签名标签对象将在使用`-s`或创建时创建`-u <keyid>`。当`-u <keyid>`不使用时，当前用户的提交者身份用于查找用于签名的 GnuPG 密钥。配置变量`gpg.program`用于指定自定义 GnuPG 二进制文件。

标记对象（用`-a`，，`-s`或创建`-u`）称为“注释”标记; 它们包含创建日期，标记名称和电子邮件，标记消息以及可选的 GnuPG 签名。而“轻量级”标签只是一个对象的名称（通常是一个提交对象）。

带注释的标签用于发布，而轻量级标签则用于私人或临时对象标签。出于这个原因，一些命名对象的git命令（如`git describe`）会默认忽略轻量级标记。

## 选项

-a --annotate

制作一个未签名的带注释的标签对象

-s --sign

使用默认的电子邮件地址密钥创建一个 GPG 签名的标签。

-u <keyid> --local-user=<keyid>

使用给定的密钥创建一个 GPG 签名的标签。

-f --force

用给定名称替换现有标签（而不是失败）

-d --delete

用给定名称删除现有标签。

-v --verify

验证给定标签名称的 GPG 签名。

-n<num>

<num> 指定在使用 -l 时打印多少行（如果有）。意味着`--list`。

默认不打印任何注释行。如果没有编号`-n`，只打印第一行。如果标签没有注释，则会显示提交消息。

-l --list

列表标签。使用可选项`<pattern>...`，例如`git tag --list 'v-*'`，仅列出与模式匹配的标签。

运行不带参数的“git tag”也会列出所有标签。该模式是一个 shell 通配符（即，使用 fnmatch（3）匹配）。可能会给出多种模式; 如果它们中的任何一个匹配，则显示该标签。

如果提供了任何其他类似列表的选项，则隐式提供此选项`--contains`。有关详细信息，请参阅每个选项的文档。

--sort=<key>

根据给定的关键字进行排序。前缀`-`按值的降序进行排序。您可以多次使用--sort = <key>选项，在这种情况下，最后一个键变为主键。还支持“版本：refname”或“v：refname”（标签名称被视为版本）。“version：refname”排序顺序也可能受“versionsort.suffix”配置变量影响。支持的密钥与中的密钥相同`git for-each-ref`。排序顺序默认为`tag.sort`变量配置的值（如果存在），否则按字典顺序排列。请参阅 git-config [1]。

--color = <when>：尊重`--format`选项中指定的任何颜色。该`<when>`字段必须是中的一个`always`，`never`或者`auto`（如果`<when>`不存在，表现得好像`always`给予）。

-i --ignore-case

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

--column=<options> --no-column

在列中显示标签列表。有关选项语法，请参阅配置变量column.tag。`--column`与`--no-column`不带选项相当于`always`和`never`分别。

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

--contains <commit>

只列出包含指定提交的标签（如果未指定，则为HEAD）。意味着`--list`。

--no-contains <commit>

只列出不包含指定提交的标签（如果未指定，则为HEAD）。意味着`--list`。

--merged <commit>

仅列出可从提交的提交（`HEAD`如果未指定）可访问的列表标记，与之不兼容`--no-merged`。

--no-merged <commit>

仅列出其提交无法从指定提交（`HEAD`如果未指定）到达的标记，与`--merged`不兼容。

--points-at <object>

只列出给定对象的标签（HEAD，如果未指定）。意味着`--list`。

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

使用给定的标签消息（而不是提示）。如果`-m`给出了多个选项，则它们的值被连接为单独的段落。意味着`-a`没有如果`-a`，`-s`或`-u <keyid>`给出。

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

从给定的文件中获取标签消息。用于`-`从标准输入读取消息。意味着`-a`没有如果`-a`，`-s`或`-u <keyid>`给出。

--cleanup=<mode>

该选项设置标签消息的清理方式。该`<mode>`可以是一个`verbatim`，`whitespace`和`strip`。该`strip`模式是默认的。该`verbatim`模式根本不会改变消息，`whitespace`仅删除前导/尾随空白行并`strip`删除空白和注释。

--create-reflog

为标签创建一个 reflog。要全局启用标记 reflogs，请参阅`core.logAllRefUpdates`git-config [1]。否定形式`--no-create-reflog`只会覆盖较早的形式`--create-reflog`，但目前并不否定这种`core.logAllRefUpdates`设置。

<tagname>

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

<commit> <object>

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

<format>

`%(fieldname)`从显示的标记ref和指向的对象中插入一个字符串。格式与 git-for-each-ref [1] 的格式相同。未指定时，默认为`%(refname:strip=2)`。

## 组态

默认情况下，`git tag`在符号默认模式下（-s）将使用提交者身份（表单`Your Name <your@email.address>`）来查找密钥。如果您想使用其他默认密钥，则可以在存储库配置中指定它，如下所示：

    [user]

        signingKey = <gpg-keyid>

`pager.tag`只有在列出标签时才受到尊重，即何时`-l`使用或暗示。默认是使用寻呼机。请参阅git-config [1]。

## 讨论

### 关于重新标记

当你标记错误提交并且你想要重新标记时，你应该怎么做？

如果你从未推出任何东西，只需重新标记即可。用“-f”替换旧的。你完成了。

但是如果你推出了一些东西（或者其他人可能会直接读取你的存储库），那么其他人就会看到旧的标签。在这种情况下，您可以执行以下两件事之一：

1. 理智的事情。只要承认你搞砸了，并使用不同的名字。其他人已经看到一个标签名称，如果你保持相同的名称，你可能会遇到两个人都拥有“版本X”的情况，但他们实际上有`different`“X”。所以把它叫做“X.1”，并且用它来完成。

1. 疯狂的事情。你真的想叫新版本“X”，`even though`其他人已经看到了旧版本。所以`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 deletethe 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`）。您通常需要从另一端的标签。

另一方面，如果您正在提取，因为您希望从其他人一次性合并，您通常不希望从那里获取标签。这种情况通常发生在靠近顶层的人群，但不限于他们。仅仅是凡人在互相拉扯时不一定要自动获得来自其他人的私人定位点标签。

通常，邮件列表中的“请拉”邮件只提供两条信息：回购网址和分行名称; 这被设计成在`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_DATE`，`GIT_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`字符。

注意 | 另外，日期部分被接受为以下格式：YYYY.MM.DD，MM / DD / YYYY和DD.MM.YYYY。
--- | ---