Reputation: 26915
I am creating releases for my Git project by retroactively adding tags to my master
branch.
Because I did not add my tags in a chronological order, Git GUI is displaying my tags in a non-chronological order, with v0.1.0
being the most recent tag, preceded by v0.1.2
and v0.1.1
.
The accepted answer to a similar question suggested creating a new annotated tag with a different date. Unfortunately, I discovered this method does not preserve tag descriptions, causing me to lose my release notes for each tag. (Thankfully I was able to restore my history from a backup)
How can I edit my annotated tags to have the same date as the commit they are tagging? (Without erasing my tag messages)
Upvotes: 3
Views: 418
Reputation: 490068
The answer you linked simply creates a new annotated tag, pointing to the existing commit. (See also What is the difference between an annotated and unannotated tag?)
The flaw in the supplied answer, as you observed, is that it does not preserve the tag's message.1 A really robust script would try to re-create the message, while doing something about PGP signatures. The problem with PGP signatures is that the only automatic thing you can do is remove them.
The git filter-branch
code has an example of how to copy an annotated tag, with a reasonable amount of robustness. Unfortunately it's 47 lines of shell script (and relies on additional shell script helpers). You would want to rewrite this to make sure that the tag exists and is an annotated tag, and keep the same commit ID and tag name.2
If you have an annotated or even PGP-signed tag that you made, you can just make a new annotated, PGP-signed tag. That is, rather than using the plumbing git hash-object -t tag -w --stdin
command that git filter-brach
uses, or even git mktag
, you can use git tag
directly. Use the technique outlined in the answer you linked-to to set the date inside the new tag object.
To save the tag's message, use git cat-file -p $tag
(or git cat-file tag $tag
) and strip off things up to the first blank line:
$ 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-----
You can, for instance, dump this into a temporary file and use git tag -F <file>
. As you can see for this case, though, this particular tag is PGP-signed. While Git will use the same data for the new tag, the signature will be invalid.
1Also, it uses a rather awkward construct for finding the commit to which the tag points. Using git rev-parse ${tag}^{commit}
would be the way to go—this lets you verify that the tag points to a commit, too.
2Remember, git filter-branch
has a --tag-name-filter
argument so it's changing the tag name as it rewrites it. It's also doing commit copying, so it has to map the old commit hash to the appropriate new commit hash. Neither of these is true in your case: you want the tag name to stay the same and the target commit object to stay the same. You just want to create a new tag object, and then update the reference part of the tag to use the new object.
Upvotes: 2