Using git diff
on PGP keys
Reasoning about changes to PGP keys is a bit difficult. A changed expiration
date, revoked user IDs, added certifications, and so, you don't see that when
looking at the file. When they're tracked in a git repo, asking git diff
is
going to be of little to no help. Either they are binary files, and you don't
see anything, or they are pem
encoded / ASCII armored files, then you might
see a bunch of changes that you can't read. But surely, git must have a solution
for this?
The solution git
provides here is called a "diff driver". You can match files
in your repo via
.gitattributes
, to set the
diff
attribute to the name of the driver you're going to use for generating a
diff. For this to work, you need to have a specific file extension that you're
using for PGP keys, so that you can match on that in your .gitattributes
file.
I'm using .pub
for this, resulting in the following line in my
.gitattributes
file:
*.pub diff=pgp
Next up is getting into diff drivers. We want a textual diff that gives us
information about what changed in the binary file, and luckily, git has a ready
made way to handle such cases generically.
diff.<driver>.textconv
allows us to set a command for generating a textual representation of the binary
blob we're examinating. Now let's add that to our git config:
[diff "pgp"]
textconv = <command>
Well.. How do we show all of the data of a PGP key? There's two options here:
- GnuPG, with
gpg --show-keys --with-fingerprint --with-subkey-fingerprints --with-sig-list
- Sequoia PGP, with
sq inspect --certifications
I prefer the output of Sequoia over the output of GnuPG, even though the GnuPG output is slightly more detailed than the Sequoia output, because it's a bit easier to grasp and there's less noise around, but that's a highly subjective matter, so if you want to try this, just play around with both and see what works for you.
Last but not least: Are we done here? Not really. The .gitattributes
documentation has a whole section about choosing between textconv versus an
external diff tool, because those also exist. An external diff tool would get
both of the files and generate a diff output completely on it's own. This has
benefits, because it allows us to be a bit smarter about what info we might want
to display. If a key has a new signature on one UID, textconv
based diffing
does give us surrounding certifications, which is not really all that
interesting information. The drawbacks to an external diff tool are additional
complexity, and worse performance, because we need to run the diff tool for each
combination of old and new file. When using textconv
, you can cache those by
setting cachetextconv
to true
, which does help if you look at git log -p
for example and the same file was edited multiple times.