This is one of several braindumps I've got, getting what are potentially
very important details about the Git stuff out of my head, so that it
doesn't matter if I become hit by a bus. Apologies if this mail seems a bit
scrambled, per -core, my brain is rather scrambled lately.
- merges are explicitly allowed, even non-fast-forwards
- all commits MUST be signed
- if you include a commit from a user:
author := non-@gentoo
committer := @gentoo
signer := $committer
The thread I started about allowing merges, I want to explain a bit of
history behind it, because it came about as a result of a change in HOW Git
upstream is doing signatures for now.
There are two things to record:
1. who really made a commit
2. who pushed the commit to the repo
They don't need to be the same person.
- Signed commits will prove #1
- Signed pushes will prove #2
Git upstream will ultimately support BOTH forms of signature, but for now, only
signed commits are available.
Good page covering Git signatures, if you don't want to read the rest of my
description below, but this page is much longer, and covers some of the related
features and checking in much more detail:
Git signed pushes:
We were originally looking for a model of signing the actual push
action, and having that recorded in Git. This was important as it
allowed the author/committer/pusher to differ, while still being
securely recorded (the signature was on the actual push action, as a
certification). This is what we had at length discussions with the Git
upstream about this:
Git signed commits:
Signed pushed were delayed in favour of more immediate work on allowing
the direct signature of the contents of a commit. These had the direct
advantage of always being included in the Git data directly.
They were built to stack cleanly on top of the fact that the existing
git repo objects were based on SHA1 hashes of other objects (see
for the DAG of a commit).
Format of the signed Git commit
If you look at the output of:
git cat-file commit $commitid
You'll see this output like this:
author Robin H. Johnson <firstname.lastname@example.org> 1338710866 +0000
committer Robin H. Johnson <email@example.com> 1338710866 +0000
commit message goes here.
That's the COMPLETE commit object.
It is also EXACTLY what gets signed.
If you look the above output (exact same command), for a signed commit:
author Robin H. Johnson <firstname.lastname@example.org> 1338710330 +0000
committer Robin H. Johnson <email@example.com> 1338710330 +0000
gpgsig -----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)
-----END PGP SIGNATURE-----
You can trivially remove the gpgsig header (the indented lines are continuations, up until the \n\n).
If you want to verify a commit, you can do:
# git show --show-signature $commitid
Or you can use cat-file, move gpgsig header to a seperate file, removing leading whitespace and the gpgsig bit, and run this yourself:
# gpg --verify commit.sig commit.no-gpgsig
Robin Hugh Johnson
Gentoo Linux: Developer, Trustee & Infrastructure Lead
E-Mail : firstname.lastname@example.org
GnuPG FP : 11ACBA4F 4778E3F6 E4EDF38E B27B944E 34884E85