Skip to content

Commit df03f10

Browse files
committed
Move tag signing from Chapter 2, add commit signing
1 parent c45e215 commit df03f10

File tree

1 file changed

+196
-0
lines changed

1 file changed

+196
-0
lines changed

book/07-git-tools/1-git-tools.asc

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,8 +603,204 @@ If you want an easier way to test the stashed changes again, you can run `git st
603603

604604
This is a nice shortcut to recover stashed work easily and work on it in a new branch.
605605

606+
=== Signing Your Work
607+
608+
Git is cryptographically secure, but it's not foolproof. If you're taking work from others on the internet and want to verify that commits are actually from a trusted source, Git has a few ways to sign and verify work using GPG.
609+
610+
==== GPG Introduction
611+
612+
First of all, if you want to sign anything you need to get GPG configured and your personal key installed.
613+
614+
[source,shell]
615+
----
616+
$ gpg --list-keys
617+
/Users/schacon/.gnupg/pubring.gpg
618+
---------------------------------
619+
pub 2048R/0A46826A 2014-06-04
620+
uid Scott Chacon (Git signing key) <[email protected]>
621+
sub 2048R/874529A9 2014-06-04
622+
----
623+
624+
If you don't have a key installed, you can generate one with `gpg --gen-key`.
625+
626+
[source,shell]
627+
----
628+
gpg --gen-key
629+
----
630+
631+
Once you have a private key to sign with, you can configure Git to use it for signing things by setting the `user.signingkey` config setting.
632+
633+
[source,shell]
634+
----
635+
git config --global user.signingkey 0A46826A
636+
----
637+
638+
Now Git will use your key by default to sign tags and commits if you want.
639+
640+
==== Signing Tags
641+
642+
If you have a GPG private key setup, you can now use it to sign new tags.
643+
All you have to do is use `-s` instead of `-a`:
644+
645+
[source,shell]
646+
----
647+
$ git tag -s v1.5 -m 'my signed 1.5 tag'
648+
649+
You need a passphrase to unlock the secret key for
650+
user: "Ben Straub <[email protected]>"
651+
2048-bit RSA key, ID 800430EB, created 2014-05-04
652+
----
653+
654+
If you run `git show` on that tag, you can see your GPG signature attached to it:
655+
656+
[source,shell]
657+
--------
658+
$ git show v1.5
659+
tag v1.5
660+
Tagger: Ben Straub <[email protected]>
661+
Date: Sat May 3 20:29:41 2014 -0700
662+
663+
my signed 1.5 tag
664+
-----BEGIN PGP SIGNATURE-----
665+
Version: GnuPG v1
666+
667+
iQEcBAABAgAGBQJTZbQlAAoJEF0+sviABDDrZbQH/09PfE51KPVPlanr6q1v4/Ut
668+
LQxfojUWiLQdg2ESJItkcuweYg+kc3HCyFejeDIBw9dpXt00rY26p05qrpnG+85b
669+
hM1/PswpPLuBSr+oCIDj5GMC2r2iEKsfv2fJbNW8iWAXVLoWZRF8B0MfqX/YTMbm
670+
ecorc4iXzQu7tupRihslbNkfvfciMnSDeSvzCpWAHl7h8Wj6hhqePmLm9lAYqnKp
671+
8S5B/1SSQuEAjRZgI4IexpZoeKGVDptPHxLLS38fozsyi0QyDyzEgJxcJQVMXxVi
672+
RUysgqjcpT8+iQM1PblGfHR4XAhuOqN5Fx06PSaFZhqvWFezJ28/CLyX5q+oIVk=
673+
=EFTF
674+
-----END PGP SIGNATURE-----
675+
676+
commit ca82a6dff817ec66f44342007202690a93763949
677+
Author: Scott Chacon <[email protected]>
678+
Date: Mon Mar 17 21:52:11 2008 -0700
679+
680+
changed the verison number
681+
--------
682+
683+
==== Verifying Tags
684+
685+
To verify a signed tag, you use `git tag -v [tag-name]`.
686+
This command uses GPG to verify the signature.
687+
You need the signer’s public key in your keyring for this to work properly:
688+
689+
[source,shell]
690+
----
691+
$ git tag -v v1.4.2.1
692+
object 883653babd8ee7ea23e6a5c392bb739348b1eb61
693+
type commit
694+
tag v1.4.2.1
695+
tagger Junio C Hamano <[email protected]> 1158138501 -0700
696+
697+
GIT 1.4.2.1
698+
699+
Minor fixes since 1.4.2, including git-mv and git-http with alternates.
700+
gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
701+
gpg: Good signature from "Junio C Hamano <[email protected]>"
702+
gpg: aka "[jpeg image of size 1513]"
703+
Primary key fingerprint: 3565 2A26 2040 E066 C9A7 4A7D C0C6 D9A4 F311 9B9A
704+
----
705+
706+
If you don’t have the signer’s public key, you get something like this instead:
707+
708+
[source,shell]
709+
----
710+
gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
711+
gpg: Can't check signature: public key not found
712+
error: could not verify the tag 'v1.4.2.1'
713+
----
714+
715+
==== Signing Commits
716+
717+
In more recent versions of Git (v1.7.9 and above), you can now also sign individual commits.
718+
If you're interested in signing commits directly instead of just the tags, all you need to do is add a `-S` to your `git commit` command.
719+
720+
[source,shell]
721+
----
722+
$ git commit -a -S -m 'signed commit'
723+
724+
You need a passphrase to unlock the secret key for
725+
user: "Scott Chacon (Git signing key) <[email protected]>"
726+
2048-bit RSA key, ID 0A46826A, created 2014-06-04
727+
728+
[master 5c3386c] signed commit
729+
4 files changed, 4 insertions(+), 24 deletions(-)
730+
rewrite Rakefile (100%)
731+
create mode 100644 lib/git.rb
732+
----
733+
734+
To see and verify these signatures, there is also a `--show-signature` option to `git log`.
735+
736+
[source,shell]
737+
----
738+
$ git log --show-signature -1
739+
commit 5c3386cf54bba0a33a32da706aa52bc0155503c2
740+
gpg: Signature made Wed Jun 4 19:49:17 2014 PDT using RSA key ID 0A46826A
741+
gpg: Good signature from "Scott Chacon (Git signing key) <[email protected]>"
742+
Author: Scott Chacon <[email protected]>
743+
Date: Wed Jun 4 19:49:17 2014 -0700
744+
745+
signed commit
746+
----
747+
748+
Additionally, you can configure `git log` to check any signatures it finds and list them in it's output with the `%G?` format.
749+
750+
[source,shell]
751+
----
752+
$ git log --pretty="format:%h %G? %aN %s"
753+
754+
5c3386c G Scott Chacon signed commit
755+
ca82a6d N Scott Chacon changed the verison number
756+
085bb3b N Scott Chacon removed unnecessary test code
757+
a11bef0 N Scott Chacon first commit
758+
----
759+
760+
Here we can see that only the latest commits is signed and valid and the previous commits are not.
761+
762+
In Git 1.8.3 and later, "git merge" and "git pull" can be told to inspect and reject when merging a commit that does not carry a trusted GPG signature with the `--verify-signatures` command.
763+
764+
If you use this option when merging a branch and it contains commits that are not signed and valid, the merge will not work.
765+
766+
[source,shell]
767+
----
768+
$ git merge --verify-signatures non-verify
769+
fatal: Commit ab06180 does not have a GPG signature.
770+
----
771+
772+
If the merge contains only valid signed commits, the merge command will show you all the signatures it has checked and then move forward with the merge.
773+
774+
[source,shell]
775+
----
776+
$ git merge --verify-signatures signed-branch
777+
Commit 13ad65e has a good GPG signature by Scott Chacon (Git signing key) <[email protected]>
778+
Updating 5c3386c..13ad65e
779+
Fast-forward
780+
README | 2 ++
781+
1 file changed, 2 insertions(+)
782+
----
783+
784+
You can also use the `-S` option with the `git merge` command itself to sign the resulting merge commit itself. The following example both verifies that every commit in the branch to be merged is signed and futhermore signs the resulting merge commit.
785+
786+
[source,shell]
787+
----
788+
$ git merge --verify-signatures -S signed-branch
789+
Commit 13ad65e has a good GPG signature by Scott Chacon (Git signing key) <[email protected]>
790+
791+
You need a passphrase to unlock the secret key for
792+
user: "Scott Chacon (Git signing key) <[email protected]>"
793+
2048-bit RSA key, ID 0A46826A, created 2014-06-04
794+
795+
Merge made by the 'recursive' strategy.
796+
README | 2 ++
797+
1 file changed, 2 insertions(+)
798+
----
799+
606800
=== Searching
607801

802+
TODO: `git grep`
803+
608804
=== Rewriting History
609805

610806
Many times, when working with Git, you may want to revise your commit history for some reason.

0 commit comments

Comments
 (0)