How do I cryptographically sign all commits on a branch?
Asked Answered
G

3

7

I have PGP key that let's me sign the commits via git commit -S. To sign my last commit I did a git commit -S --amend --no-edit and it signed my commit.

Now, I want to sign all the commits that are there in the branch filtered.

I tried: git filter-branch --commit-filter 'git commit -S --amend --no-edit'

and it gives me an error message:

$ git filter-branch --commit-filter 'git commit --amend --no-edit -S' HEAD
Rewrite 07b0ac12f5fe1d8963d7ae0ac7fbda50cb6e74a9 (1/10)gpg: skipped "Anubhav Saini <[email protected]>": secret key not available
gpg: signing failed: secret key not available
error: gpg failed to sign the data
fatal: failed to write commit object
could not write rewritten commit

Another issue: raising another git commit --amend --no-edit -S results in:

(filter-test)$ git commit -S --no-edit --amend

You need a passphrase to unlock the secret key for
user: "Anubhav Saini <[email protected]>"

[filter-test c5ea180] Removing defer and async from scripts
 4 files changed, 28 insertions(+), 28 deletions(-)

Questions

  1. How to batch sign the commit messages?
  2. What is raising another sign doing actually and behind the scene?
Grieg answered 9/4, 2016 at 4:45 Comment(0)
P
3

Consider that rewriting history to sign all the commits in a branch may be overkill.

Because of the git object model, a commit exists in context. Signing the head commit alone also imputes your blessing to its immediate parent (or parents if it is a merge commit) as well as their parents in turn all the way back to day one of your repository.

This is why signing a tag for an official release, for example, is sufficient. Git objects are immutable because each one’s SHA-1 object name is derived from its content. Therefore, starting from a known trusted point allows you and others to chase pointers (which is what git log, git checkout, git fsck, and so on do behind the scenes) to verify integrity.

If you are working on unpublished history, consider condensing the history with git merge --squash or git rebase -i and signing the resulting commit.

Portraitist answered 9/4, 2016 at 14:39 Comment(0)
C
1

Make a backup of your repository before you get started:

tar czf my-repo-backup-2022-03-04.tar.gz ./my-repo

Sign all commits in since first commit without modifying commit date:

FIRST_COMMIT="$(git rev-list --max-parents=0 HEAD)"
git filter-branch --commit-filter 'git commit-tree -S "$@";' "${FIRST_COMMIT}"..HEAD

With help from GuyPaddock here and Chris Johnsen here.

Chilton answered 4/3, 2022 at 11:45 Comment(0)
C
0

probably you should setup a gpg-agent with a decent timeout for passphrase validity (enough to run the whole sequence of rewrites). See this Arch wiki page for help. Thus, can enter the passphrase once, before the rewrite, and then all invocation of gpg will use that unlocked key for a while.

Chapiter answered 9/4, 2016 at 5:24 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.