I created a tag and forgot to sign it, then pushed the tag to GitHub. Is it possible to just sign that tag retroactively, or do I have to create a new tag?
I have read the man page for git tag
and googled a bit, but have come up with no clues that adding a signature to an already existing tag is possible.
No you would need to::
replace it with a tag using the same name:
git tag <tag name> <tag name> -f -s
but first set the committer date, in order to not change the date
set GIT_COMMITTER_DATE="$(git log -1 --format=%aD <tag_name>)"
As mrts adds in the comments, since the tag was already pushed:
You also need to force push the updated tag with
git push origin <tag_name> -f
Starting with Git 2.42 (Q3 2023), you can sign only the tags which need it, using:
git for-each-ref --format='%(refname) %(signature)' refs/tags | python re-sign-tags.py
^^^^^^^^^^^^
(new with Git 2.42)
And re-sign-tags.py
import sys
import subprocess
def verify_tag(refname, signature):
grade = signature.split(":")[1]
if grade == "good":
print("Tag '%s' is signed with a good signature." % refname)
else:
print("Tag '%s' is signed with a bad signature." % refname)
def re_sign_tag(refname, signature):
signer = signature.split(":")[1]
print("Re-signing tag '%s' with key '%s'." % (refname, signer))
subprocess.run(["git", "tag", "-f", refname, refname, "-s"], check=True)
if __name__ == "__main__":
for refname, signature in sys.stdin:
if refname.startswith("refs/tags/"):
if verify_tag(refname, signature):
re_sign_tag(refname, signature)
With Git 2.42 (Q3 2023), the "git for-each-ref
"(man) family of commands learned placeholders related to GPG signature verification.
See commit 26c9c03, commit 2f36339 (04 Jun 2023) by Kousik Sanagavarapu (five-sh
).
(Merged by Junio C Hamano -- gitster
-- in commit 81ebc54, 14 Jul 2023)
ref-filter
: add new "signature" atomCo-authored-by: Hariom Verma
Co-authored-by: Jaydeep Das
Co-authored-by: Nsengiyumva Wilberforce
Mentored-by: Christian Couder
Mentored-by: Hariom Verma
Signed-off-by: Kousik Sanagavarapu
Duplicate the code for outputting the signature and its other parameters for commits and tags in ref-filter from pretty.
In the future, this will help in getting rid of the current duplicate implementations of such logic everywhere, when ref-filter can do everything that pretty is doing.The new atom "signature" and its friends are equivalent to the existing pretty formats as follows:
%(signature) = %GG %(signature:grade) = %G? %(siganture:signer) = %GS %(signature:key) = %GK %(signature:fingerprint) = %GF %(signature:primarykeyfingerprint) = %GP %(signature:trustlevel) = %GT
git for-each-ref
now includes in its man page:
signature
The GPG signature of a commit.
signature:grade
Show "G" for a good (valid) signature, "B" for a bad signature, "U" for a good signature with unknown validity, "X" for a good signature that has expired, "Y" for a good signature made by an expired key, "R" for a good signature made by a revoked key, "E" if the signature cannot be checked (e.g. missing key) and "N" for no signature.
signature:signer
The signer of the GPG signature of a commit.
signature:key
The key of the GPG signature of a commit.
signature:fingerprint
The fingerprint of the GPG signature of a commit.
signature:primarykeyfingerprint
The primary key fingerprint of the GPG signature of a commit.
signature:trustlevel
The trust level of the GPG signature of a commit. Possible outputs are
ultimate
,fully
,marginal
,never
andundefined
.