题 你如何重命名Git标签?


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

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

git tag -l

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


969
2018-06-22 18:09


起源


您是否使用了相同的调用,即如果旧标签是带注释/签名的标签,那么这个新标签还是轻量级标签? - Jakub Narębski
不正确的旧标记和所需的新标记都应该注释和未签名。旧标签是使用'git tag -a bad_tag_name'创建的,所以我想按照'git tag -a good_tag_name'的方式做一些事情。 - Brandon Fosdick
我应该指出,我还希望这个神奇的标记重命名过程保留正在重命名的标记的注释。实际上,我真的想改变名称而不是别的。 - Brandon Fosdick
git log --oneline --decorate --graph 清理标签时很有帮助。 - Joel Purra
您可以在一行中重命名标记:请参阅 我的答案如下 - VonC


答案:


以下是重命名标记的方法 old 至 new

git tag new old
git tag -d old
git push origin :refs/tags/old
git push --tags

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

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

git pull --prune --tags

1646
2018-04-19 16:51



如果标签被注释,新标签将不具有旧标签的消息,但它是一个有用的信息 - NickSoft
@NickSoft,我刚刚使用带注释的标签完成了上述操作。消息被从旧复制到新的就好了。也许我有更新版本的git? - katyhuff
需要注意的一点是,如果你使用 git tag new old 如果“旧”不是轻量级标签,那么“旧”会使其成为“新”标签。要看到这一点,请尝试: git tag -m tralala old; git tag new old; git tag -d old; git cat-file tag new | grep old。这是因为“new”指向“旧”标记,而不是指向“旧”指向的指针。 - Uwe Kleine-König
git push origin :refs/tags/old 可以简化为 git push origin :old 我认为。 - Jesse Glick
我建议将“git push --tags”更改为更明确的标签“git push origin refs / tags / new”。您不希望无意中推送其他标签。 - chrish


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

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


271
2017-12-09 13:34



上面的答案略有可取,因为它包括 git push origin 商业。 - Roly
最简单的方法,非常适合重命名使用Gitflow创建的先前版本标记 - RousseauAlexandre
警告:使用 git tag new old 将创建一个指向旧标签的标签, 不 旧标签的提交。 (看到 为什么我不能从Git GUI签出我的标签?) - Steven Vascellaro


除了其他答案:

首先,你需要建立一个 别号 的  标记名称,指向原始提交:

git tag new old^{}

然后你需要删除旧的 本地

git tag -d old

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

# 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

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

git push origin --tags

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

请注意 Git Tag变化带来的影响 给消费者一个包!


101
2018-04-27 11:42



警告:使用 git tag new old 将创建一个指向旧标签的标签, 不 旧标签的提交。 (看到 为什么我不能从Git GUI签出我的标签?) - Steven Vascellaro
@StevenVascellaro感谢您的链接。下次请提交 编辑  - 回答也是社区的努力。谢谢。 - kaiser
我没有进行编辑,因为我还没有为自己测试代码。 (注意链接问题的提交日期) - Steven Vascellaro
一旦我们做到了 git tag new old^{}那我们就不需要了 git tag new_tag_name old_tag_name (第一步)。 - Breaking Benjamin
好的,我测试并编辑了答案。 - user894763


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

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

或者,

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

这太疯狂了,因为:

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

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

所有的礼貌 手册页


25
2018-06-22 18:10



或者您可以标记(使用正确的名称)此错误命名的标记。 - Jakub Narębski
谢谢,我已经超过了那个手册页了一百万次。幸运的是,坏标签尚未在任何地方发布。即使它是,这是一个内部项目,我是唯一的开发人员(目前)。我认为我对tarring和羽毛都相当安全,但前提是我可以让repo与docs相匹配。 - Brandon Fosdick
我有时会使用标签作为我自己的个人参考。例如。它可能是一个'ok_jb'标签。我使用它,因为我使用的一些人无法为我的平台构建,所以有时会出现构建错误。然后我可以通过签出该标签快速获得构建版本。当新的源代码构建时,我只是移动标记,或者我将其重命名为构建##,其中##是一个数字(取决于项目)。我还可以通过添加标签来强调引入特殊功能的时间。
答案很差。 “不要这样做”永远不是“我怎么能这样做?”的正确答案。用户并没有问你是否认为这样做是好主意,或者人们是否愿意这样做。如果有人问“我怎么能切断我的手”,要么告诉他是怎么做的,要么让他独自一人,但他不需要有人告诉他切手可能不是一个好主意。你可以做到。您可以添加新标记并删除旧标记,这在技术上是可行的,即使在远程存储库中也是如此。 - Mecki
这似乎回答了“我如何使现有标签指向不同的版本?”的问题。而不是OP的问题,“如何重命名标签?”还不清楚告诉别人搞砸的人是怎么解决问题的(尽管一般来说这是一个好主意)。 - LarsH


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

git push origin <refs/tags/old-tag>:<refs/tags/new-tag> :<refs/tags/old-tag> && git tag -d <old-tag>

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

所以想法是推动:

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

见例如“更改git存储库中标签的命名约定?”。


22
2018-06-16 14:20



这会保留注释吗? - Brandon Fosdick
@BrandonFosdick是的,它适用于带注释的标签。 - VonC
要小心这一点 保留原始标签名称 在注释标签的注释!!我不确定这实际上是否意味着什么,至少在当前版本中。 - gbr
@VonC我不确定我明白你在问什么;也许我不清楚:注释对象包含一个 标签 设置为标记名称的字段,您可以看到它 git cat-file -p <tag>;用你的方法在我的系统上我得到'重命名'标签引用(<new-tag>),但它 标签 场还在 <old-tag>。 - gbr
@gbr不是OP想要的吗?他提到“我应​​该指出,我还希望这个神奇的标签重命名过程保留重命名的标签中的注释。实际上,我真的想改变名称而不是别的”(stackoverflow.com/questions/1028649/how-do-you-rename-a-git-tag/...) - VonC


作为其他答案的补充,我添加了一个别名,只需一步即可完成所有操作,使用更熟悉的* 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' -"

用法:

git renametag old new

19
2017-11-17 15:00





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

mv .git/refs/tags/OLD .git/refs/tags/NEW

6
2017-07-13 09:24



如果你的裁判被打包,即如果你已经跑了,这将不起作用 git gc 最近 - forivall
这也只会影响当地的回购。如果你配置了一个遥控器,我不确定这会产生什么负面影响。我不推荐这种方法。 - therealklanni
另请注意,对于带注释的标签,这可能会更麻烦,因为其他内容中的“注释”blob包含标签的原始名称。实际上我不确定这是否被任何东西使用(希望至少通过验证标签),但我不会冒险。 - gbr
@gbr这很好用。(当然,@ forivall的注释应该被考虑在内。)这个技巧已经在ALT Sisyphus构建系统中大量使用了很长时间。看看如何存储包的来源,例如: git.altlinux.org/gears/g/gear.git 。可读的标签就像 2.0.7-ALT1 是维护者提交给构建系统的签名标签。神秘的标签 GB-西西弗斯 - task164472.200 由构建系统放在那里以跟踪已从此源构建和发布pkg的任务ID。他们是愚蠢的副本(cp),维护者的信息不受影响。 - imz -- Ivan Zakharyaschev
@ imz - IvanZakharyaschev很高兴知道,我不会过于信任,虽然它不会在未来产生一些产品的问题;没有真正规范git存储库格式和预期的交互,所以当它可行时,我会努力以最不可思议的方式干净地做事 - gbr


简单的部分是重命名本地标签。更难的部分是远程部分。 这个技巧背后的想法是将旧标签/分支复制到新标签/分支并删除旧标签/分支,而无需结帐。

远程标签重命名/远程分支→标签转换: (注意: :refs/tags/

git push <remote_name> <old_branch_or_tag>:refs/tags/<new_tag> :<old_branch_or_tag>

远程分支重命名/远程标记→分支转换: (注意: :refs/heads/

git push <remote_name> <old_branch_or_tag>:refs/heads/<new_branch> :<old_branch_or_tag>

输出重命名远程标记:

D:\git.repo>git push gitlab App%2012.1%20v12.1.0.23:refs/tags/App_12.1_v12.1.0.23 :App%2012.1%20v12.1.0.23

Total 0 (delta 0), reused 0 (delta 0)
To https://gitlab.server/project/repository.git
 - [deleted]               App%2012.1%20v12.1.0.23
 * [new tag]               App%2012.1%20v12.1.0.23 -> App_12.1_v12.1.0.23

1
2018-02-17 13:41