你如何重命名Git标签?

Bra*_*ick 1162 git git-tag

今天我正在浏览一个项目的日志,并意识到我不久前发了一个标签名称.有没有办法重命名标签?谷歌没有发现任何有用的东西.

我意识到我可以查看标记版本并制作新标签,我甚至尝试过.但这似乎创建了一个不太正确的标签对象.一个,

git tag -l
Run Code Online (Sandbox Code Playgroud)

相对于所有其他标签,它不按顺序列出.我不知道这是否重要,但它让我相信新标签对象不是我想要的.我可以忍受,因为我真的只关心标签名称与文档匹配,但我宁愿"正确",假设有正确的方法来做到这一点.

Cas*_*son 1935

以下是将标记重命名oldnew:

git tag new old
git tag -d old
git push origin :refs/tags/old
git push --tags
Run Code Online (Sandbox Code Playgroud)

push命令中的冒号从远程存储库中删除标记.如果你不这样做,当你拉动时,Git会在你的机器上创建旧标签.

最后,确保其他用户删除已删除的标记.请告诉他们(同事)运行以下命令:

git pull --prune --tags
Run Code Online (Sandbox Code Playgroud)

  • @NickSoft,我刚刚使用带注释的标签完成了上述操作.消息被从旧复制到新的就好了.也许我有更新版本的git? (25认同)
  • 我建议将"git push --tags"更改为更明确的标签"git push origin refs/tags/new".您不希望无意中推送其他标签. (25认同)
  • `git push origin:refs/tags/old`可以简化为`git push origin:old`我认为. (24认同)
  • 如果标签被注释,新标签将不会有旧标签的消息,但它是一个有用的信息 (19认同)
  • **警告**:使用`git tag new old`将创建一个指向旧标签的标签,*不是旧标签的提交.(参见[*为什么我不能从Git GUI签出我的标签?*](/sf/ask/3449861411/)) (9认同)
  • 需要注意的一点是,如果你使用`git tag new old`就是"old"使它成为"new"标签iff"old"不是一个轻量级标签.要看到这一点,请尝试:`git tag -m tralala old; git tag new old; git tag -d old; git cat-file标签新| grep old`.那是因为"new"指向"旧"标记,而不是指向"旧"指向的指针. (8认同)
  • 很好的回答,谢谢.我可以建议将`git tag new old`更改为`git tag new tags/old`,因为这更明确地指的是旧标签而不是其他东西? (4认同)
  • 我相信我正确地遵循了这些步骤,但是`git pull --prune --tags`没有摆脱其他版本的repo中的旧标签,我仍然必须在那里明确删除它们.使用git 2.8.3 (3认同)
  • 要从远程删除旧标签,您还可以执行`git push -d [remote] [tag]`。 (3认同)
  • 要添加到@chrish注释,`--tags`包括注释和轻量级标记,这可能不是意图.只推送重命名的标签使用`git push origin [new-tag-name]` (2认同)

小智 290

最初的问题是如何重命名标签,这很简单:首先创建NEW作为OLD的别名:git tag NEW OLD然后删除OLD : git tag -d OLD.

关于"Git方式"和(in)完整性的引用是不合适的,因为它讨论的是保留标记名称,但使其引用不同的存储库状态.

  • 上面的答案略有可取,因为它包括`git push origin`业务. (3认同)
  • **警告**:使用`git tag new old`将创建一个指向旧标签的标签,*不是旧标签的提交.(参见[*为什么我不能从Git GUI签出我的标签?*](/sf/ask/3449861411/)) (3认同)

kai*_*ser 111

除了其他答案:

首先,你需要建立一个别名了的标签名称,指向原来的承诺:

git tag new old^{}
Run Code Online (Sandbox Code Playgroud)

然后你需要在本地删除旧的:

git tag -d old
Run Code Online (Sandbox Code Playgroud)

然后删除远程位置上的标记:

# Check your remote sources:
git remote -v
# The argument (3rd) is your remote location,
# the one you can see with `git remote`. In this example: `origin`
git push origin :refs/tags/old
Run Code Online (Sandbox Code Playgroud)

最后,您需要将新标记添加到远程位置.在您完成此操作之前,不会添加新标记:

git push origin --tags
Run Code Online (Sandbox Code Playgroud)

为每个远程位置迭代这个.

请注意,Git Tag更改对包的消费者的影响!

  • 我用这个解决方案作为一句台词,它似乎很有魅力!`git tag NEW_TAG OLD_TAG^{} && git tag -d OLD_TAG && git Push origin :refs/tags/OLD_TAG && git Push origin NEW_TAG` (2认同)

Rob*_*anu 28

如果它已发布,则无法将其删除(不会有被涂焦油和羽毛的风险).'Git方式'是:

理智的事情.只是承认你搞砸了,并使用不同的名字.其他人已经看过一个标签名称,如果你保持相同的名称,你可能会遇到两个人都有"版本X"的情况,但他们实际上有不同的"X".所以只需称它为"X.1"并完成它.

或者,

疯狂的事情.你真的想把新版本称为"X",即使其他人已经看过旧版本.所以再次使用git-tag -f,好像你还没有发布旧版本一样.

它太疯狂了,因为:

Git没有(也不应该)改变用户背后的标签.因此,如果有人已经获得旧标签,那么在树上进行git-pull不应该只是让它们覆盖旧标签.

如果有人从你那里得到了一个发布标签,你就不能通过更新自己的标签来改变标签.这是一个很大的安全问题,因为人们必须能够信任他们的标签名称.如果你真的想做疯狂的事情,你需要了解它,告诉别人你搞砸了.

所有礼貌的手册页.

  • 或者您可以标记(使用正确的名称)此错误命名的标记. (6认同)
  • 谢谢,我已经超过了那个手册页了一百万次.幸运的是,坏标签尚未在任何地方发布.即使它是,这是一个内部项目,我是唯一的开发人员(目前).我认为我对tarring和羽毛都相当安全,但前提是我可以让repo与docs相匹配. (6认同)
  • 答案很差."不要这样做"永远不是"我怎么能这样做?"的正确答案.用户并没有问你是否认为这样做是好主意,或者人们是否愿意这样做.如果有人问"我怎么能切断我的手",要么告诉他是怎么做的,要么让他独自一人,但他不需要有人告诉他切手可能不是一个好主意.你可以做到.您可以添加新标记并删除旧标记,这在技术上是可行的,即使在远程存储库中也是如此. (5认同)
  • 这似乎回答了"我如何使现有标签指向不同的版本?"的问题.而不是OP的问题,"如何重命名标签?" 目前还不清楚告诉别人搞砸的人是怎么解决这个问题的(尽管一般来说这是一个好主意). (5认同)

Von*_*onC 25

这个维基页面有一个有趣的单行,它提醒我们,我们可以推几个参考:

git push origin <refs/tags/old-tag>:<refs/tags/new-tag> :<refs/tags/old-tag> && git tag -d <old-tag>
Run Code Online (Sandbox Code Playgroud)

并要求其他克隆人做 git pull --prune --tags

所以想法是推动:

  • <new-tag>对于<old-tag>:引用的每个提交<refs/tags/old-tag>:<refs/tags/new-tag>,
  • 删除<old-tag>::<refs/tags/old-tag>

请参阅示例" 更改git存储库中标记的命名约定? ".

  • @gbr不是OP想要的吗?他提到"我应​​该指出,我也希望这个神奇的标签重命名过程能够保留重命名的标签中的注释.实际上,我真的想改变名称,而不是其他任何东西"(http://stackoverflow.com/问题/ 1028649 /怎么办 - 你 - 重命名-A-git的标签/ 24245862#comment846114_1028649) (3认同)
  • 与本页上的大多数答案不同,这保留了标签日期。 (2认同)

Jar*_*ipp 25

作为其他答案的补充,我添加了一个别名,只需一步即可完成所有操作,使用更熟悉的*nix move命令.参数1是旧标记名称,参数2是新标记名称.

[alias]
    renameTag = "!sh -c 'set -e;git tag $2 $1; git tag -d $1;git push origin :refs/tags/$1;git push --tags' -"
Run Code Online (Sandbox Code Playgroud)

用法:

git renametag old new
Run Code Online (Sandbox Code Playgroud)

  • 这对我不起作用,因为它在 `!sh` 处失败(问题是关于 Windows Git),但是,在将格式更新为以下格式后,它起作用了: `renametag = "!f() { git tag $2 $1 ; git tag -d $1; git push origin :refs/tags/$1; git push --tags; }; f"`. (2认同)

vik*_*sia 9

对于一个或几个标签,请遵循3步方法。

步骤1:确定当前标签指向的提交的提交/对象ID

     command: git rev-parse <tag name>
     example: git rev-parse v0.1.0-Demo
     example output: db57b63b77a6bae3e725cbb9025d65fa1eabcde
Run Code Online (Sandbox Code Playgroud)

步骤2:从存储库中删除标签

     command: git tag -d <tag name>
     example: git tag -d v0.1.0-Demo
     example output: Deleted tag 'v0.1.0-Demo' (was abcde)
Run Code Online (Sandbox Code Playgroud)

第3步:创建一个新标签,指向与旧标签所指向的提交ID相同的提交ID

     command: git tag -a <tag name>  -m "appropriate message" <commit id>
     example: git tag -a v0.1.0-full  -m "renamed from v0.1.0-Demo" db57b63b77a6bae3e725cbb9025d65fa1eabcde
     example output: Nothing or basically <No error>
Run Code Online (Sandbox Code Playgroud)

一旦本地git做好了标记名称更改的准备,就可以将这些更改推回原点,以供其他人使用。


小智 6

对于喜欢冒险的人来说,可以在一个命令中完成:

mv .git/refs/tags/OLD .git/refs/tags/NEW
Run Code Online (Sandbox Code Playgroud)

  • 如果您的参考文件被打包,即最近您运行`git gc`,这将无效 (7认同)
  • 这也只会影响当地的回购.如果您配置了遥控器,我不确定这会产生什么负面影响.我不推荐这种方法. (2认同)
  • 另请注意,对于带注释的标签,这可能会更加麻烦,因为“注释”blob 包含标签的原始名称。实际上我不确定它是否被任何东西使用(希望至少通过验证标签),但我不会冒险。 (2认同)
  • @gbr 这工作得很好。(当然,要考虑@forivall 的注释。)这个技巧已经在 ALT Sisyphus 构建系统中大量使用了很多年。查看包的源代码是如何存储的,例如:http://git.altlinux.org/gears/g/gear.git。像**2.0.7-alt1**这样的可读标签是维护者提交给构建系统的签名标签。构建系统将神秘标签 **gb-sisyphus-task164472.200** 放置在那里,以跟踪已从此源构建和发布 pkg 的任务 ID。它们是哑副本(`cp`),维护者的消息未受影响。 (2认同)

M. *_*tin 6

这个答案通过使用现有标签中的标签信息创建一个重复的带注释的标签来解决这个问题——包括所有标签信息,如标签、消息和标签日期。

SOURCE_TAG=old NEW_TAG=new; deref() { git for-each-ref \
"refs/tags/$SOURCE_TAG" --format="%($1)" ; }; \
GIT_COMMITTER_NAME="$(deref taggername)" \
GIT_COMMITTER_EMAIL="$(deref taggeremail)" \
GIT_COMMITTER_DATE="$(deref taggerdate)" git tag "$NEW_TAG" \
"$(deref "*objectname")" -a -m "$(deref contents)"

git tag -d old

git push origin new :old
Run Code Online (Sandbox Code Playgroud)

更新SOURCE_TAGNEW_TAG值以匹配您的旧标签名称和新标签名称。

动机

据我所知,所有其他答案都有微妙的问题,或者没有完全复制标签的所有内容(例如,他们使用新的标签日期,或当前用户的信息作为标签)。他们中的许多人都发出重新标记警告,尽管这不适用于这种情况(这是为了将标签名称移动到不同的提交,而不是重命名为不同名称的标签)。我已经做了一些挖掘,我相信我已经拼凑出解决这些问题的解决方案。

目标

git-tag文档指定了带注释的标签的部分。要真正成为一个难以区分的重命名,这些元素在新标签中应该是相同的。

标签对象(用-a-s、 或创建的-u)被称为“带注释的”标签;它们包含创建日期、标记者名称和电子邮件、标记消息和可选的 GnuPG 签名。

我只是在这个答案中解决未签名的标签,尽管将此解决方案扩展到签名标签应该是一件简单的事情。

程序

old示例中使用了一个名为的带注释的标记,并将重命名为new.

第 1 步:获取现有标签信息

首先,我们需要获取现有标签的信息。这可以使用for-each-ref

命令:

git for-each-ref refs/tags --format="\
Tag name: %(refname:short)
Tag commit: %(objectname:short)
Tagger date: %(taggerdate)
Tagger name: %(taggername)
Tagger email: %(taggeremail)
Tagged commit: %(*objectname:short)
Tag message: %(contents)"
Run Code Online (Sandbox Code Playgroud)

输出:

Tag commit: 88a6169
Tagger date: Mon Dec 14 12:44:52 2020 -0600
Tagger name: John Doe
Tagger email: <j.doe@example.com>
Tagged commit: cda5b4d
Tag name: old
Tag message: Initial tag

Body line 1.
Body line 2.
Body line 3.
Run Code Online (Sandbox Code Playgroud)

第 2 步:在本地创建重复标签

可以使用在步骤 1 中从现有标签收集的信息创建具有新名称的重复标签。

提交 ID 和提交消息可以直接传递给git tag.

可以使用git 环境变量 GIT_COMMITTER_NAMEGIT_COMMITTER_EMAIL、来设置标记器信息(姓名、电子邮件和日期)GIT_COMMITTER_DATE。在此上下文中的日期用法在On Backdating Tags文档中进行了描述git tag;另外两个是我通过实验想出来的。

GIT_COMMITTER_NAME="John Doe" GIT_COMMITTER_EMAIL="j.doe@example.com" \
GIT_COMMITTER_DATE="Mon Dec 14 12:44:52 2020 -0600" git tag new cda5b4d -a -m "Initial tag

Body line 1.
Body line 2.
Body line 3."
Run Code Online (Sandbox Code Playgroud)

两个标签的并排比较表明它们在所有重要方面都是相同的。这里唯一不同的是标签本身的提交引用,这是预期的,因为它们是两个不同的标签。

命令:

git for-each-ref refs/tags --format="\
Tag commit: %(objectname:short)
Tagger date: %(taggerdate)
Tagger name: %(taggername)
Tagger email: %(taggeremail)
Tagged commit: %(*objectname:short)
Tag name: %(refname:short)
Tag message: %(contents)"
Run Code Online (Sandbox Code Playgroud)

输出:

Tag commit: 580f817
Tagger date: Mon Dec 14 12:44:52 2020 -0600
Tagger name: John Doe
Tagger email: <j.doe@example.com>
Tagged commit: cda5b4d
Tag name: new
Tag message: Initial tag

Body line 1.
Body line 2.
Body line 3.

Tag commit: 30ddd25
Tagger date: Mon Dec 14 12:44:52 2020 -0600
Tagger name: John Doe
Tagger email: <j.doe@example.com>
Tagged commit: cda5b4d
Tag name: old
Tag message: Initial tag

Body line 1.
Body line 2.
Body line 3.
Run Code Online (Sandbox Code Playgroud)

作为单个命令,包括检索当前标签数据:

Tag commit: 580f817
Tagger date: Mon Dec 14 12:44:52 2020 -0600
Tagger name: John Doe
Tagger email: <j.doe@example.com>
Tagged commit: cda5b4d
Tag name: new
Tag message: Initial tag

Body line 1.
Body line 2.
Body line 3.

Tag commit: 30ddd25
Tagger date: Mon Dec 14 12:44:52 2020 -0600
Tagger name: John Doe
Tagger email: <j.doe@example.com>
Tagged commit: cda5b4d
Tag name: old
Tag message: Initial tag

Body line 1.
Body line 2.
Body line 3.
Run Code Online (Sandbox Code Playgroud)

第三步:在本地删除现有标签

接下来,应在本地删除现有标签。如果您希望保留旧标签和新标签(即复制标签而不是重命名),则可以跳过此步骤。

SOURCE_TAG=old NEW_TAG=new; deref() { git for-each-ref "refs/tags/$SOURCE_TAG" --format="%($1)" ; }; GIT_COMMITTER_NAME="$(deref taggername)" GIT_COMMITTER_EMAIL="$(deref taggeremail)" GIT_COMMITTER_DATE="$(deref taggerdate)" git tag "$NEW_TAG" "$(deref "*objectname")" -a -m "$(deref contents)"
Run Code Online (Sandbox Code Playgroud)

第 4 步:将更改推送到远程存储库

假设您在远程存储库中工作,现在可以使用git push以下方式推送更改:

git tag -d old
Run Code Online (Sandbox Code Playgroud)

这会推送new标签,并删除old标签。


归档时间:

查看次数:

238038 次

最近记录:

6 年 前