Am Freitag, 31. Januar 2014 08:28:03 UTC+1 schrieb Konstantin Khomoutov:
> On Thu, 30 Jan 2014 22:59:12 -0800 (PST) 
> Tom Wieczorek < <javascript:>> wrote: 
> > I'd like to sign git commits with my GPG key after they have been 
> > committed. I know that I can sign them at commit time using git -S. 
> > But, is it possible to sign a single commit afterwards? I use an IDE 
> > that doesn't support signing. So I'd like to add my signature to 
> > those commits from the command line. I also know that there is an 
> > autosign git config value, but this one scares me a bit. I'd like to 
> > sign commits proactively, not just by accident. 
> IIRC, you can't sign a commit after it has been created because, well, 
> it has been created already, and objects in the Git database are 
> immutable. 

I already expected, that, bud didn't find any reference when searching the 
internet. Thanks for clarifying. I wasn't sure of how commit signing is 
implemented. If the signature would have been some sort of metadata 
attached to the actual commit, it could have been added after the commit, 
without changing its hash. But it seems to be part of the commit itself, if 
I understand correctly.

> So, basically, I'd say you have two possibilities: 
> * You should be able to amend the tip commit.  This would essentially 
>   replace it (that's what `git amend` does).  This should work for 
>   unpushed commits, and obviously only works for the tip commit 
>   (what HEAD points at). 
* You might attach an annotated tag to any commit you like. 
>   Annotated tags may be signed, and that's what, say, Git project 
>   does to do releases: a signed annotated tag is attached to a commit 
>   which designates a released state. 
>   Use `git tag -a` for this. 

I think the latter option is the most sensible.  The idea is that 
> there's no need to sign *each* commit because once you signed a tag, 
> you authenticated the whole subgraph of commits reachable from this 
> tag--simply because the tag references its commit by its SHA-1 name, 
> it, in turn, reference all the objects comprising the committed state 
> by the SHA-1 names of those objects, and its parent commits--by their 
> SHA-1 names as well.  Since we take SHA-1 names to be cryptographically 
> strong (exploitation of a collision attack for injection of 
> sensible malicious data into the repository is infeasible), by 
> attaching a signed annotated tag to a commit you effectively sign all 
> objects reachable from that one--even though they're not signed 
> directly. 
I was already aware of that. The idea was to prove that some distinct 
changeset has been made by me, and just me, but I assume you got that 
already. If I sign a tag, I sign all ancestors transitively. However, I 
cannot guarantee that there was a bad/spoofed commit pushed by someone 
else, without reviewing the whole history between HEAD and the first signed 
commit/tag. I have to think about it. Perhaps I just sign the tip commit of 
my branch just before opening a pull request, or something like that.

Anyway, thank you for your detailed explanation. Much appreciated.

> Note that the Git repo even has the maintainer's public key injected 
> into it--for easier verification; it's done like this: 
>   $ git tag gpg-key $(git hash-object -w <my-gpg-pub.key) 
>   $ git push hub gpg-key 

You received this message because you are subscribed to the Google Groups "Git 
for human beings" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
For more options, visit

Reply via email to