How to retain commit gpg-signature after interactive rebase squashing?
Asked Answered
C

5

39

When I want to squash some commits by interactive rebase:

git rebase -i HEAD~3

And then:

pick cbd03e3 Final commit (signed)
s f522f5d bla-bla-bla (signed)
s 09a7b7c bla-bla (signed)

# Rebase c2e142e..09a7b7c onto c2e142e
...

The final commit haven't gpg-signature despite that all of those commits have same signature. Is it possible to retain commit gpg-signature after interactive rebase squash?

Circle answered 18/9, 2013 at 14:0 Comment(1)
"that all of those commits have same signature" this doesn't make any sense. You're probably generating the different signatures from the same key, but the signatures themself can not be the same.Galliett
A
66

Like Cupcake stated, you can't retain the old signature from the unsquashed commits, but you can sign the new squashed commit if you rebase like this:

git rebase --interactive [email protected] HEAD~4

Adding [email protected] as an argument will sign the final squashed commit.

Augmenter answered 25/3, 2015 at 18:18 Comment(5)
Is this still current in git 1.8.3.1 or later? Running this command throws this: error: unknown option '[email protected]'Elviaelvie
@jflory7 I'm using git 2.13.3 and this is still valid for me.Augmenter
if that doesn't work, you can do a git rebase -i HEAD~4 and edit each commit with git commit --amend -S .Doublejointed
I remember setting git config variables commit.gpgsign and user.signingkey to autosign commits for me - does this setting not apply to rebases?Ecbolic
@KrishnanShankar not if you don't say edit. If you say edit, a commit will be the result of each step of the interactive rebase and it's you who has to issue git commit and then you can add -S, for example ... or pass some other options.Homeomorphism
W
16

It doesn't make sense that you would be able to. The whole point of a gpg signature is to verify that code hasn't been tampered with. If you could keep the signature after modifying the history, that would defeat the whole purpose.

I don't currently sign my Git code with gpg so I don't know the exact details, but I guess it probably hashes the final commit object of a tree. When you rebase like in your example, the Final commit will have a different sha1 ID, so it's not the same object as before the rebase, so having the same gpg signature is probably impossible, and like I said, it wouldn't make sense.

Whitebook answered 18/9, 2013 at 14:42 Comment(3)
It makes sense if they are YOUR commits, and you want to retain A signature (rather than THE signature).Catastrophism
@AndyHayden then you should resign the commits. it has helped me conceptually to prior to rebasing checkout a new branch. I am working on work-01. I do git checkout work-02. I rebase, resolve merge conflicts, and squash commits as appropriate. work-01 has not changed at all. the commits are all still there and as they were. some of the commits might also exist in work-02, some might be nearly identical but if a single character has changed it has a new commit hash id. this exercise helped me understand git rebasing.Jujutsu
This is interesting, but I wonder if it's 100% valid. We work on feature branches and our Gitlab is configured to allow MRs only if they can be fast-forwarded (quasi-linear history), so we rebase those branches if something has changed in base branch. When I commit to feature branch and sign commit, then my colleague rebases branch, GPG signature should remain untouched IF commit is picked without changes (so my signature is still valid, because it is the exact code that I commited and signed). However GPG signature is lost when signed commit is rebased by other person (we've just checked it).Notepaper
T
6

To reinforce the fact you don't keep signature on rebased commits, git 2.9.x+ (Q3 2016) will clearly state that a git pull --rebase would not check signature (since the rebase part would lost them)

See commit c57e501 (20 May 2016) by Alexander Hirsch (``).
(Merged by Junio C Hamano -- gitster -- in commit 73bc4b4, 20 Jun 2016)

pull: warn on --verify-signatures with --rebase

git-pull silently ignores the --verify-signatures option when running --rebase, potentially leaving users in the belief that the rebase operation would check for valid GPG signatures.

Implementing --verify-signatures for git rebase was talked about, but doubts for a valid workflow rose up. Since you usually merge other's branches into your branch you might have an interest that their side has a valid GPG signature.

Rebasing, on the other hand, is to rebuild your branch on top of other's work, in order to push the result back, and it is too late to reject their work even if you find their commits lack acceptable signature.

Let's warn users that the --verify-signatures option is ignored during "pull --rebase"; users do not wonder what would happen if their commits lack acceptable signature that way.

Tonita answered 21/6, 2016 at 0:13 Comment(0)
A
6

One option is to set a commit.gpgSign setting to true. This will always sign the commits including the rebased commits.

To do it locally in a repo:

git config commit.gpgSign true

To do it globally:

git config --global commit.gpgSign true
Alow answered 27/4, 2021 at 7:37 Comment(0)
H
1

There was one method that didn't get mentioned yet, but in effect it equates to an interactive rebase with edit on each commit to-be-signed and a manual amend/commit (with -S), but with a predetermined command and in an automated fashion:

git rebase --exec 'git commit --amend --no-edit -S' HEAD~3

The -i (--interactive) is implied with --exec given, according to the documentation, so it's not given above.

Here we rebase against HEAD~3 as in the question, and git commit --amend --no-edit -S each of the commits. This should usually ask for the passphrase of the PGP key once and then rush through for the remaining commits.

NB: it should go without saying, but since it was commented: just as with the other methods you'll only want to do that with your own commits. Remove the --no-edit and you'll be dropped into the editor, showing (in a comment at the bottom) what changes you're dealing with. This way you can verify that the commits are yours (unless you already did by way of git log or so).


Arguably to tell Git to sign when you haven't configured it globally, you could probably also use git -c commit.gpgSign=true (or other related configuration options) in the command passed via --exec.

Homeomorphism answered 4/8, 2023 at 12:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.