如何在不丢失标记消息的情况下更改带注释的Git标记的日期?

时间:2018-03-23 18:35:18

标签: git git-tag

我正在通过追溯性地向我的master分支添加标签来为我的Git项目创建版本。

因为我没有按照时间顺序添加我的标签,Git GUI以非时间顺序显示我的标签,v0.1.0是最新的标签,前面是v0.1.2和{{ 1}}。

对类似问题的接受答案建议creating a new annotated tag with a different date。不幸的是,我发现此方法 保留标记说明,导致我丢失每个标记的发行说明。 (谢天谢地,我能够从备份中恢复我的历史记录)

如何编辑带注释的标签,使其与标记的提交具有相同的日期? (不删除我的标记消息)

Git tag history out of order

1 个答案:

答案 0 :(得分:0)

The answer you linked只是创建一个新的带注释的标签,指向现有的提交。 (另请参阅 What is the difference between an annotated and unannotated tag?

正如您所观察到的,所提供答案中的缺陷是它不保留标记的消息 1 一个非常强大的脚本会尝试在对PGP签名做一些事情的同时重新创建消息。 PGP签名的问题在于,您可以执行的唯一自动事件是删除它们。

The git filter-branch code has an example of how to copy an annotated tag, with a reasonable amount of robustness.不幸的是它有47行shell脚本(并依赖于其他shell脚本助手)。您可能希望重写此项以确保标记存在并且是带注释的标记,并保留相同的提交ID和标记名称。 2

如果你有制作的带注释或甚至PGP签名的标签,你可以制作一个带注释的新PGP签名标签。也就是说,您可以直接使用git hash-object -t tag -w --stdin,而不是使用git filter-brach使用的管道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将为 new 标记使用相同的数据,但签名将无效。

1 此外,它使用一个相当笨拙的构造来查找标记指向的提交。使用git rev-parse ${tag}^{commit}将是一种方法 - 这可以让您验证标记是否也指向提交。

2 请记住,git filter-branch有一个--tag-name-filter参数,因此当它重写时,更改标记名称。它也在进行提交复制,因此必须将旧的提交哈希映射到适当的新提交哈希。在您的情况下,这些都不是这样:您希望标记名称保持不变,目标提交对象保持不变。您只想创建一个新标记 object ,然后更新标记的引用部分以使用新对象。