如何在不丢失标签信息的情况下更改已注释的Git标签日期?

3
我正在通过在我的master分支上追加标签来创建我的Git项目的发布版本。由于我没有按照时间顺序添加标签,因此Git GUI显示我的标签是非时间顺序的,其中v0.1.0是最新的标签,前面是v0.1.2v0.1.1
类似问题的被接受答案建议创建一个具有不同日期的新注释标签。不幸的是,我发现这种方法不能保留标签描述,导致我失去了每个标签的发布说明(幸运的是,我能够从备份中恢复历史记录)。 如何编辑我的注释标签,使它们具有与它们标记的提交相同的日期?(不删除我的标签消息)

Git tag history out of order


你的标签消息是多行的吗?对于单行消息,我可以修改脚本以保留消息(实际上是提取和重新应用它们)。但对于多行消息,这是一个问题,至少对我来说是这样,因为我的标签是有签名的,我无法提取没有签名的多行消息。 - phd
@phd 我的标签使用多行消息来列出版本之间的更改。 - Stevoisiak
1个回答

2
您链接的答案”只是创建一个新的带注释的标签,指向现有的提交。(另请参见注释标签和非注释标签之间的区别是什么?
所提供答案的缺陷,正如您所观察到的那样,是它没有保留标签消息1 一个真正强大的脚本会尝试重新创建消息,并处理PGP签名。PGP签名的问题在于,您唯一可以自动执行的操作是删除它们。

git filter-branch的代码提供了一个复制带有适当健壮性的注释标签的示例。不幸的是,这是47行shell脚本(并且依赖于其他shell脚本辅助工具)。您需要重新编写此代码以确保标签存在且为注释标签,并保持相同的提交ID和标签名称。2

如果您拥有一个您自己创建的已注释或甚至PGP签名的标签,那么您可以直接创建一个新的带注释、PGP签名的标签。也就是说,不使用git filter-brach使用的git hash-object -t tag -w --stdin命令,甚至不使用git mktag,您可以直接使用git tag。使用您链接到的答案中概述的技术来设置新标签对象内的日期。

要保存标签的消息,请使用git cat-file -p $tag(或git cat-file tag $tag)并删除第一个空行之前的内容:
$ git cat-file tag v2.9.4 | sed '1,/^$/d'
Git 2.9.4
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAABAgAGBQJZC/1WAAoJELC16IaWr+bLreYP/0HhgbODcdFE9tFtxHUMwqVz
kw6E2HtKRugb1hJulo+WNk40CL3Fg/YvP2CWaqsOA6woBOofLMGv1VzT8kkavyiM
UCL4Gjcm4rHaUrln7Gr+gIfEdlCT3cbJ7cNoEYRegbxd0vG/M/AyS4kOLfLQc7LQ
TMO5yqq1wJRJO5WhwqbW6XDwhsjWnQhKuobWpVr+AB1SPNQfWlWVnpBAdhseV2Ui
Q79GXhxSYT+es72CuhFbQc/Crn0iS0sFo5ljA9baDUzj7SOqfcDhNJFEF+xthIcN
DOFgHyUAoTKSIreMX5JO5tFCYDiAfNtkTd+8BLbfvsc2/zC+Qv0UxXh8aH3DzHIV
qsyZILXCjtkaxtqZfDIgE+4u8nPAuO/9ubJH9eunz1bbK2rJAMPeIo0Kmp6yRHIb
gvgG6gCR29TdqdgZN22UjsV94Bq/PqWKb2dN6NAVIRDi/TOhK8woLxfVdNKyT68s
3edTe/XzKVo18PediSt6KgzXJpUuIHJlE5IWq1cKysElw4fv5jOiHBWvH9LFRAXS
JTLXv6sS5Bk+KB2sgbTvoLwh0qC7g+cxyeBInqbIVP1spGLAsAJADHMmPJxx3yt3
PfsiARSRgoDh5J45smZPgJj/kMUg78SKXyBc3GgfH48tY5rAwVDe3TMMjEFVxa7n
zAbtKPw4yovxWW4/3WTj
=8LG8
-----END PGP SIGNATURE-----

例如,您可以将其转储到临时文件中,然后使用git tag -F <file>。但是,正如您在此示例中所看到的,这个特定的标签是PGP签名的。虽然Git将使用相同的数据来创建新标签,但签名将无效。
此外,它使用了一个相当笨拙的结构来查找标签所指向的提交。使用 git rev-parse ${tag}^{commit} 是正确的方法——这样可以验证标签是否指向了一个提交。
请记住,git filter-branch 有一个 --tag-name-filter 参数,因此在重写标签时会更改标签名称。它还执行提交复制,因此必须将旧的提交哈希映射到适当的新提交哈希。你的情况不是这样:你希望标签名称保持不变,并且目标提交对象保持不变。你只想创建一个新的标签对象,然后更新标签的引用部分以使用新对象。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接