“
您链接的答案”只是创建一个新的带注释的标签,指向现有的提交。(另请参见
注释标签和非注释标签之间的区别是什么?)
所提供答案的缺陷,正如您所观察到的那样,是它没有保留
标签消息。
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
参数,因此在重写标签时会更改标签名称。它还执行提交复制,因此必须将旧的提交哈希映射到适当的新提交哈希。你的情况不是这样:你希望标签名称保持不变,并且目标提交对象保持不变。你只想创建一个新的标签对象,然后更新标签的引用部分以使用新对象。