背景

之前在更新 GitHub 的 GPG 公钥的时候,不小心手贱删掉了原来的 GPG 公钥。这就导致了很严重的后果 —— 我之前所有的 commits 都变成了 Unverified 的状态。由于本地也没有原 GPG 公钥的备份,本强迫症一度抓狂想自裁

不过即便如此,我们还是可以使用新的 GPG 密钥重新签名之前所有的 Git commits,然后 git push --force 无脑解决问题

警告:以下操作具有危险性,请仅在私人 Repo 中使用,使用前注意备份数据。

方法 1:使用 git rebase + git filter-branch

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

# 这一步会重新提交所有之前的 commits,因而会改变 commit time
# 而 git rebase 的 --committer-date-is-author-date 参数会与 --root 参数冲突
# 因此我们需要再用 git filter-branch 修正 commit time

git filter-branch --env-filter 'export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"'

方法 2:git filter-branch one-liner

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

# git filter-branch 在触发前需要稍等,还会警告你这是核武器级的选项 XD

如果仅需要对特定的 committer email 进行重签名,还可以:

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

参考