263

我们的 Git 存储库中有几个带注释的标签。旧标签包含虚假消息,我们希望将其更新为新样式。

% git tag -n1
v1.0 message
v1.1 message
v1.2 message
v2.0 Version 2.0 built on 15 October 2011.

在这个例子中,我们想让 v1.x 消息看起来像 v2.0 消息。我们将如何做到这一点?

4

10 回答 10

302
git tag <tag name> <tag name>^{} -f -m "<new message>"

这将创建一个具有相同名称的新标签(通过覆盖原始标签)。

于 2011-10-18T20:24:32.937 回答
103

要更新复杂的消息,只需指定带注释的标记选项-a或带符号的标记选项-s

git tag <tag name> <tag name>^{} -f -a

这将打开一个包含旧标签消息内容的编辑器。

于 2013-01-02T23:26:52.317 回答
46

git tag <tag name> <tag name>^{} -f -a

这是一个改进:如果没有^{}它,将创建一个引用旧标签对象的新标签对象,它们都将具有相同的标签名称。

<tag name>^{}将解析标签/引用,直到找到第一个提交哈希。

于 2014-05-08T04:03:02.100 回答
41

TL;博士

您可以通过删除您的标签并在欺骗日期和作者时重新创建它来做到这一点:

> git tag -d <tag-name>
> [GIT_COMMITTER_DATE=<original-commit-date>] \
> [GIT_AUTHOR_NAME=<original-author-name>] \
> git tag <tag-name> [commit]

整个故事:

基于Sungram的回答(最初作为编辑提出):

1.接受的答案

这是对AndyEric Hu答案的改进。他们的答案将创建一个引用旧标签对象的新标签对象,并且两者都将具有相同的名称。

为了说明这一点,请考虑以下内容:

> git tag tag1 tag1 -f -a  # accepted answer
> git rev-list --objects -g --no-walk --all
[ example output: ]
6bdcc347fca041a5138f89fdf5276b3ebf9095d5
260ab7928d986472895b8c55e54569b3f3cb9517 tag1
a5797673f610914a45ef7ac051e3ee831a6e7c25 tag1
f22d6308c3cd330a3b0d86b9bf05562faf6b6f17

> git show tag1
tag tag1
Tagger: [tagger]
Date:   [date of updated tag]
[Updated description]

tag tag1
Tagger: [tagger]
Date:   [date of original tag]
[Original description]

[tagged commit details]

2. Sungram的改进

<tag name>^{}用作的第二个参数将git tag删除所有以前的同名标签。

考虑前一个终端会话的延续:

> git tag tag1 tag1^{} -f -a  # suggested improvement
> git rev-list --objects -g --no-walk --all
[ example output: ]
6bdcc347fca041a5138f89fdf5276b3ebf9095d5
75f02acacfd7d91d55b5bcfdfb1f00aebeed15e3 tag1
f22d6308c3cd330a3b0d86b9bf05562faf6b6f17 

> git show tag1
tag tag1
Tagger: [tagger]
Date:   [date of updated tag]
[Updated description]

[tagged commit details]

3. 保存日期

最后,如果您想将原始标签的日期保留为更新标签的日期,请使用一些 awk(或类似的)魔法,或者只是粘贴您想要的日期。以下是第二个示例的替代品(否则原始日期将因覆盖而丢失):

> GIT_COMMITTER_DATE="$(git show tag1 |                              # get info about the tag cascade including the date original of the original tag
> awk '{
>     if ($1 == "Date:") {
>         print substr($0, index($0,$3))
>     }
> }' |                                                               # extract all the dates from the info
> tail -2 | head -1)"                                               `# get the second to last date, as the last one is the commit date` \
> git tag tag1 tag1^{} -a -f                                         # finally, update the tag message, but save the date of the old one
>
> git rev-list --objects -g --no-walk --all
6bdcc347fca041a5138f89fdf5276b3ebf9095d5
e18c178f2a548b37799b100ab90ca785af1fede0 tag1
f22d6308c3cd330a3b0d86b9bf05562faf6b6f17
> git show tag1
tag tag1
Tagger: [tagger]
Date:   [date of original tag]
[Updated description]

[tagged commit details]

参考:

4. 自己动手做

或者更新标签,您可以删除它们并重新创建它们。事实证明,更新只是添加一个新标签并使其指向旧标签,或者,只是隐式删除旧标签并创建一个新标签以指向相同的提交。

您可以通过发出以下命令来实现:

> git tag -d <tag-name>
> [GIT_COMMITTER_DATE=<original-commit-date>] \
> [GIT_AUTHOR_NAME=<original-author-name>] \
> git tag <tag-name> [commit]

[optional]是一个可选字段;<required>是必填字段。当然,您可以在git tag通常的命令之后添加任何标志。

于 2015-03-12T20:24:36.440 回答
15

@Andy 2016 年的解决方案

git tag <tag-name> <tag-name> -f -a

。之后,与

git show

命令,我们将看到具有相同名称的堆栈标签。

它在 commit 处添加一个具有相同标签名称和新消息的新标签<tag-name>。但它不会删除旧标签。这是此命令的一个特例:

git tag [<commit> | <old-tag>] <tag-name>

但只是<old-tag><tag-name>.


正确的解决方案很简单,只需更新标签即可。

git tag <tag-name> -f -a

请记住,这里只有一个

如果我们想要更改标签,而不是HEAD,我们需要一个额外的<commit>参数。

git tag <commit> <tag-name> -f -a
于 2016-07-07T03:46:36.187 回答
9

我们想让 v1.x 消息看起来像 v2.0 消息

在 Git 2.17(2018 年第 2 季度)中,将有一个替代方法来创建标签git tag <tag name> <tag name> -f -m "<new message>",因为“ git tag”学习了一个明确的“ --edit”选项,该选项允许进一步编辑通过“ -m”和“ ”给出的消息。-F

请参阅Nicolas Morey-Chaisemartin ( ) 的提交 9eed6e4(2018 年 2 月 6 日(由Junio C Hamano 合并——提交 05d290e中,2018 年 3 月 6 日)nmorey
gitster

tag: 添加--edit选项

添加一个--edit允许修改-mor提供的消息的选项,-F方法相同git commit --edit

于 2018-03-10T23:38:15.953 回答
4

您将不得不使用-fforce 标志再次标记。

git tag v1.0 -f -m "actual message"
于 2011-10-18T20:28:19.607 回答
4

使用上面的答案(尤其是Sungam 的),这是我的别名 one-liner for .gitconfig。替换现有标签并保留提交日期。

[alias]
tm = "!sh -c 'f() { export GIT_COMMITTER_DATE=$(git log -1 --format=%ci $0); git tag -f -a $0 $0^{}; }; f '"

改进?

于 2016-01-05T20:04:23.073 回答
0

如果您使用的是像smartgit这样的 GUI

  1. 使用新消息在相同位置再次创建相同的标签
  2. 选择“覆盖现有标签”
  3. 强制将标签推送到上游存储库
于 2020-03-06T01:02:15.353 回答
0

这是一组别名,应该根据此处的现有答案(尤其是stanm's)为您完成:

# Edit an existing tag, preserving the date and tagger
tag-amend = "!f() { : git tag ;\
    eval \"`git x-tag-environment-string`\";\
    git tag -a -f --edit -m \"$(git x-tag-message \"$1\")\" \"$1\" \"$1^{}\" \"${@:2}\";\
}; f"

# Rewrite an existing tag, preserving the date and tagger (accepts -m and -F)
tag-rewrite = "!f() { : git tag ;\
    eval \"`git x-tag-environment-string`\";\
    git tag -a -f \"$1\" \"$1^{}\" \"${@:2}\";\
}; f"

# Helpers to Extract the Tag Data
x-tag-data = tag -l --format
x-tag-message = x-tag-data '%(contents)'
x-tagger-name = x-tag-data '%(taggername)'
x-tagger-email = x-tag-data '%(taggeremail)'
x-tag-date = x-tag-data '%(taggerdate:rfc2822)'
x-tag-environment-string = "!f() { echo '\
    export GIT_COMMITTER_DATE=${GIT_COMMITTER_DATE-`git x-tag-date \"$1\"`};\
    export GIT_COMMITTER_NAME=${GIT_COMMITTER_NAME-`git x-tagger-name \"$1\"`};\
    export GIT_COMMITTER_EMAIL=${GIT_COMMITTER_EMAIL-`git x-tagger-email \"$1\"`};\
';}; f"

这些别名接受单个标签名称和 git 标签的任何其他标志,并且可以很容易地修改以支持名称更改。

用法:

# opens editor to edit existing message
git tag-amend <tag name>

# add a new paragraph to the existing message
git tag-amend <tag name> -m "<new paragraph>"

# replace the message with a new one
git tag-rewrite <tag name> -m "<new message>"

支持轻量级标签

使用creatordate,creatornamecreatoremail代替tagger...变体。creator...快捷方式将使用(tagger...如果存在)并回退到committer....

于 2020-07-28T20:11:17.213 回答