Velvet Star Monitor

Standout celebrity highlights with iconic style.

news

Can you GPG sign old commits?

Writer Emily Wong

Git now has the ability to sign commits with git commit -S, which is great, but sometimes I forget the flag to commit, and sometimes I mail myself patches which I apply with am, and that command doesn't have a flag for signing.

Is there a way to add a signature to an already recorded commit?

3

9 Answers

  1. Go into interactive rebase mode.
  2. Add the following line after each commit you want to sign

    exec git commit --amend --no-edit -S

This will run this command after picking each commit.

UPDATE:

Easier way to do this is:

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

This rebases everything till development (or any hash) and you don't have to copy paste after every commit.

11

Signing a commit changes its contents, so more recent commits depending on it will change their hash.

If you just want to sign the most recent commit, git commit -S --amend will work.

3

I use git rebase -i --root ( see Rewriting History ) and change pick to edit.

Then I use git commit -S --amend --no-edit && git rebase --continue (on Windows) for each commits.

This is manually sign for each commits. I hope we will found better solution.

2

If you need to GPG sign all commits SINCE a particular commit on the current branch, you can use the following instead:

git filter-branch --commit-filter 'git commit-tree -S "$@";' <COMMIT>..HEAD

Where <COMMIT> is the commit id (e.g. abc123e5).

This has the added benefit that it does not disturb the commit metadata (including commit date). The commit hashes will change, though (since it's a digest of the contents of each commit, and a signature is being added to each commit).

If you also would like to stop getting prompted for your GPG passphrase on every commit, also see this answer:

NOTE: Switching from gpg to gpg2 for GIT signing will require you to re-import your private key in GPG 2.

3

If you want to filter only specific commits and sign only them you can use filter-branch:

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

This is useful if, for some reason, you want to sign only your own commits.

I also stumbled on the same problem and here is my solution:

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

this will sign all of my commits from the first initial commit and also bypass commit hook that I set up using husky. No need to change pick to edit.

1

If no filtering on commit is needed, then it is preferred to use rebase than filter-branch:

git rebase -i master --exec 'git commit --amend --no-edit --no-verify -S --reset-author'

Else, you can leave untouched the commits you don't own.
Set the following alias in ~/.gitconfig (replace with your email address):

resign = "!_() { : git checkout ; [ \"$#\" -eq 0 ] && echo 'Usage: resign <rev-list>' && exit 2; \ git filter-branch --commit-filter ' \ if [ \"$GIT_COMMITTER_EMAIL\" = \"\" ]; then git commit-tree -S \"$@\"; else git commit-tree \"$@\"; fi' $1; }; _"

Then for instance, to resign all your commits in the current branch pulled from master, do:

git resign master..

Credits to previous answers byBarryMode and Roberto Leinardi

To sign off last N commits, you can also do:

git rebase HEAD~N --signoff
3

here's the one I use for all commits, yes it will re-write history:

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

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy