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

标签 git git-tag

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

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

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

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

Git tag history out of order

最佳答案

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参数,因此它在重写标签名称时更改标签名称。它还在进行提交复制,因此它必须将旧提交 HashMap 到适当的新提交哈希。在您的情况下,这些都不是真的:您希望标记名称保持不变并且目标提交对象保持不变。您只想创建一个新标签对象,然后更新标签的引用部分以使用新对象。

关于git - 如何在不丢失标记消息的情况下更改带注释的 Git 标记的日期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49456330/

相关文章:

git - 如何使用 git/AWS CLI 管理 AWS Lambda 代码?

git - 如何欺骗 git-svn 来识别用 svn 进行的 merge ?

git - 将 git pull 请求从 bitbucket 移动到 github?

git - 如何在 Git 中编辑现有标记消息?

git - 如何克隆特定的 Git 标签

Git:如何让日志只显示与模式匹配的标签?

git "rebase"只有一些来自外部存储库的提交?

git - 致命:目标路径 'opencv_contrib'已存在,并且不是空目录

git - 克隆没有标签的仓库?

git - 是否每个git标记都有关联的提交ID?