我可以为已创建的Git标签签名吗?

22

我创建了一个标签,忘记签名,然后将标签推送到GitHub上。是否可以追溯地给这个标签签名,还是必须创建一个新的标签?

我阅读了git tag的man手册并进行了一些搜索,但没有找到为已存在的标签添加签名的线索。

2个回答

19
不,你需要这样做:
  • 用相同的名称替换为一个标签

      git tag <tag name> <tag name> -f -s
    
  • 但首先设置提交者日期,以便不更改日期

      set GIT_COMMITTER_DATE="$(git log -1 --format=%aD <tag_name>)"
    

mrts评论中所提到的,由于标签已经被推送:

您还需要使用 git push origin <tag_name> -f 进行强制推送已更新的标签。


从 Git 2.42(2023 年第三季度)开始,您可以仅对需要签名的标签使用以下方法进行签名:
git for-each-ref --format='%(refname) %(signature)' refs/tags | python re-sign-tags.py
                                      ^^^^^^^^^^^^
                                   (new with Git 2.42)

而且 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)

在 Git 2.42 (2023 年第三季度) 中,"git for-each-ref"(man) 命令系列学会了与 GPG 签名验证相关的占位符。

查看提交 26c9c03提交 2f36339(2023年6月4日)由Kousik Sanagavarapu (five-sh)
(由Junio C Hamano -- gitster --提交 81ebc54中合并,2023年7月14日)

ref-filter: 添加新的 "signature" 原子 Co-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现在在其手册页面中包含了:

签名

提交的GPG签名。

signature:grade

显示“G”表示好(有效)的签名,显示“B”表示坏的签名,显示“U”表示未知有效性的好签名,显示“X”表示已过期的好签名,显示“Y”表示由已过期密钥制作的好签名,显示“R”表示由已吊销密钥制作的好签名,“E”表示无法检查签名(例如缺失密钥),显示“N”表示没有签名。

signature:signer

提交的GPG签名制造者。

signature:key

提交的GPG签名密钥。

signature:fingerprint

提交的GPG签名指纹。

signature:primarykeyfingerprint

提交的GPG签名主密钥指纹。

signature:trustlevel

提交的GPG签名信任级别。可能的输出值为 ultimate, fully, marginal, neverundefined


请参考类似主题的内容(包括推送):https://dev59.com/22Ei5IYBdhLWcg3wCYKY#21741848 - VonC
1
您还需要使用 git push origin <tag_name> -f 命令强制推送更新的标签。 - mrts
2
@mrts 很好的观点。我已经把你的评论包含在答案中以增加可见度。 - VonC

4

我知道这是一个老问题,但根据VonC的说法。我创建了一个单行bash脚本,可以自动遍历您存储库中的所有标签并对它们进行签名。您只需要接受或更改旧标记中设置的消息即可。以下是我想出的命令:

git for-each-ref refs/tags | awk '{print $3}' | cut -c11- | xargs -I % sh -c 'git tag % % -f -s'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接