有没有办法对所有以前的提交进行 gpg 签名?

Is there a way to gpg sign all previous commits?

正如标题所说,我正在寻找一种方法来 gpg 签署我以前在存储库中的所有提交(最好不要为每次提交输入我的密码)。

谢谢!

你可以,但它必须重写你的整个历史。

签署提交会更改提交,而提交会更改其提交 ID。由于提交 ID 取决于先前的提交 ID,因此必须更改之后的所有提交。不管怎样,你都签了。

如果它是一个没有其他人在处理的个人存储库,那么这不是问题。如果它是与其他协作者的存储库,请将其视为进行主要的 rebase。

您可以使用 git filter-branch 来重做每个使用 -S 选项的提交。

git filter-branch --commit-filter 'git commit-tree -S "$@";' -- --all

至于不必为每次提交都输入密码,您需要配置 gpg 以使用 gpg-agent. If you're familiar with ssh-agent it's a similar idea, it's a little process that you give the password to once and keeps it stored in memory for you. How you do that depends on your operating system and setup. On OS X I let GPG Tools 处理它。

如果您只想过滤特定的提交并仅对其签名,您可以使用 filter-branch:

git filter-branch --commit-filter 'if [ "$GIT_COMMITTER_EMAIL" = "user@domain.com" ];
  then git commit-tree -S "$@";
  else git commit-tree "$@";
  fi' HEAD

如果您出于某种原因只想签署自己的提交,这将很有用。

我的做法是

git rebase --exec 'git commit --amend --no-edit -n -S' -i 8fd7b22

8fd7b22 之后开始的所有提交都将重新设置基准,除了签名之外没有任何更改。要更改从第一个开始的所有提交,您可以使用 --root(因为 Git v1.7.12):

 git rebase --exec 'git commit --amend --no-edit -n -S' -i --root

将更改传播到我使用的遥控器

git push --force

注意,这将更新“gpg made”日期时间,例如,GitHub 会将其视为提交日期。 Git 本身保留原始日期和新日期,git log --show-signature 清楚地显示原始提交的时间和最后一次签名的时​​间。

我想解决的用例是在保持原始提交日期的同时签署我以前的所有提交。

签署相关提交

git rebase -i --root
git commit --amend -S --no-edit &&  git rebase --continue # for all the relevant commits

Return 提交日期为作者日期并强制推送(不要忘记之前备份)。

git rebase --committer-date-is-author-date -i --root # return 
git push origin main -f

可以使用其他答案实现自动化。