Documentation / howto / using-signed-tag-in-pull-request.txton commit Merge branch 'jk/receive-pack-deadlocks-with-early-failure' (f87f742)
   1From: Junio C Hamano <gitster@pobox.com>
   2Date: Tue, 17 Jan 2011 13:00:00 -0800
   3Subject: Using signed tag in pull requests
   4Abstract: Beginning v1.7.9, a contributor can push a signed tag to her
   5 publishing repository and ask her integrator to pull it. This assures the
   6 integrator that the pulled history is authentic and allows others to
   7 later validate it.
   8Content-type: text/asciidoc
   9
  10How to use a signed tag in pull requests
  11========================================
  12
  13A typical distributed workflow using Git is for a contributor to fork a
  14project, build on it, publish the result to her public repository, and ask
  15the "upstream" person (often the owner of the project where she forked
  16from) to pull from her public repository. Requesting such a "pull" is made
  17easy by the `git request-pull` command.
  18
  19Earlier, a typical pull request may have started like this:
  20
  21------------
  22 The following changes since commit 406da78032179...:
  23
  24   Froboz 3.2 (2011-09-30 14:20:57 -0700)
  25
  26 are available in the Git repository at:
  27
  28   example.com:/git/froboz.git for-xyzzy
  29------------
  30
  31followed by a shortlog of the changes and a diffstat.
  32
  33The request was for a branch name (e.g. `for-xyzzy`) in the public
  34repository of the contributor, and even though it stated where the
  35contributor forked her work from, the message did not say anything about
  36the commit to expect at the tip of the for-xyzzy branch. If the site that
  37hosts the public repository of the contributor cannot be fully trusted, it
  38was unnecessarily hard to make sure what was pulled by the integrator was
  39genuinely what the contributor had produced for the project. Also there
  40was no easy way for third-party auditors to later verify the resulting
  41history.
  42
  43Starting from Git release v1.7.9, a contributor can add a signed tag to
  44the commit at the tip of the history and ask the integrator to pull that
  45signed tag. When the integrator runs `git pull`, the signed tag is
  46automatically verified to assure that the history is not tampered with.
  47In addition, the resulting merge commit records the content of the signed
  48tag, so that other people can verify that the branch merged by the
  49integrator was signed by the contributor, without fetching the signed tag
  50used to validate the pull request separately and keeping it in the refs
  51namespace.
  52
  53This document describes the workflow between the contributor and the
  54integrator, using Git v1.7.9 or later.
  55
  56
  57A contributor or a lieutenant
  58-----------------------------
  59
  60After preparing her work to be pulled, the contributor uses `git tag -s`
  61to create a signed tag:
  62
  63------------
  64 $ git checkout work
  65 $ ... "git pull" from sublieutenants, "git commit" your own work ...
  66 $ git tag -s -m "Completed frotz feature" frotz-for-xyzzy work
  67------------
  68
  69Note that this example uses the `-m` option to create a signed tag with
  70just a one-liner message, but this is for illustration purposes only. It
  71is advisable to compose a well-written explanation of what the topic does
  72to justify why it is worthwhile for the integrator to pull it, as this
  73message will eventually become part of the final history after the
  74integrator responds to the pull request (as we will see later).
  75
  76Then she pushes the tag out to her public repository:
  77
  78------------
  79 $ git push example.com:/git/froboz.git/ +frotz-for-xyzzy
  80------------
  81
  82There is no need to push the `work` branch or anything else.
  83
  84Note that the above command line used a plus sign at the beginning of
  85`+frotz-for-xyzzy` to allow forcing the update of a tag, as the same
  86contributor may want to reuse a signed tag with the same name after the
  87previous pull request has already been responded to.
  88
  89The contributor then prepares a message to request a "pull":
  90
  91------------
  92 $ git request-pull v3.2 example.com:/git/froboz.git/ frotz-for-xyzzy >msg.txt
  93------------
  94
  95The arguments are:
  96
  97. the version of the integrator's commit the contributor based her work on;
  98. the URL of the repository, to which the contributor has pushed what she
  99  wants to get pulled; and
 100. the name of the tag the contributor wants to get pulled (earlier, she could
 101  write only a branch name here).
 102
 103The resulting msg.txt file begins like so:
 104
 105------------
 106 The following changes since commit 406da78032179...:
 107
 108   Froboz 3.2 (2011-09-30 14:20:57 -0700)
 109
 110 are available in the Git repository at:
 111
 112   example.com:/git/froboz.git tags/frotz-for-xyzzy
 113
 114 for you to fetch changes up to 703f05ad5835c...:
 115
 116   Add tests and documentation for frotz (2011-12-02 10:02:52 -0800)
 117
 118 -----------------------------------------------
 119 Completed frotz feature
 120 -----------------------------------------------
 121------------
 122
 123followed by a shortlog of the changes and a diffstat.  Comparing this with
 124the earlier illustration of the output from the traditional `git request-pull`
 125command, the reader should notice that:
 126
 127. The tip commit to expect is shown to the integrator; and
 128. The signed tag message is shown prominently between the dashed lines
 129  before the shortlog.
 130
 131The latter is why the contributor would want to justify why pulling her
 132work is worthwhile when creating the signed tag.  The contributor then
 133opens her favorite MUA, reads msg.txt, edits and sends it to her upstream
 134integrator.
 135
 136
 137Integrator
 138----------
 139
 140After receiving such a pull request message, the integrator fetches and
 141integrates the tag named in the request, with:
 142
 143------------
 144 $ git pull example.com:/git/froboz.git/ tags/frotz-for-xyzzy
 145------------
 146
 147This operation will always open an editor to allow the integrator to fine
 148tune the commit log message when merging a signed tag.  Also, pulling a
 149signed tag will always create a merge commit even when the integrator does
 150not have any new commit since the contributor's work forked (i.e. 'fast
 151forward'), so that the integrator can properly explain what the merge is
 152about and why it was made.
 153
 154In the editor, the integrator will see something like this:
 155
 156------------
 157 Merge tag 'frotz-for-xyzzy' of example.com:/git/froboz.git/
 158
 159 Completed frotz feature
 160 # gpg: Signature made Fri 02 Dec 2011 10:03:01 AM PST using RSA key ID 96AFE6CB
 161 # gpg: Good signature from "Con Tributor <nitfol@example.com>"
 162------------
 163
 164Notice that the message recorded in the signed tag "Completed frotz
 165feature" appears here, and again that is why it is important for the
 166contributor to explain her work well when creating the signed tag.
 167
 168As usual, the lines commented with `#` are stripped out. The resulting
 169commit records the signed tag used for this validation in a hidden field
 170so that it can later be used by others to audit the history. There is no
 171need for the integrator to keep a separate copy of the tag in his
 172repository (i.e. `git tag -l` won't list the `frotz-for-xyzzy` tag in the
 173above example), and there is no need to publish the tag to his public
 174repository, either.
 175
 176After the integrator responds to the pull request and her work becomes
 177part of the permanent history, the contributor can remove the tag from
 178her public repository, if she chooses, in order to keep the tag namespace
 179of her public repository clean, with:
 180
 181------------
 182 $ git push example.com:/git/froboz.git :frotz-for-xyzzy
 183------------
 184
 185
 186Auditors
 187--------
 188
 189The `--show-signature` option can be given to `git log` or `git show` and
 190shows the verification status of the embedded signed tag in merge commits
 191created when the integrator responded to a pull request of a signed tag.
 192
 193A typical output from `git show --show-signature` may look like this:
 194
 195------------
 196 $ git show --show-signature
 197 commit 02306ef6a3498a39118aef9df7975bdb50091585
 198 merged tag 'frotz-for-xyzzy'
 199 gpg: Signature made Fri 06 Jan 2012 12:41:49 PM PST using RSA key ID 96AFE6CB
 200 gpg: Good signature from "Con Tributor <nitfol@example.com>"
 201 Merge: 406da78 703f05a
 202 Author: Inte Grator <xyzzy@example.com>
 203 Date:   Tue Jan 17 13:49:41 2012 -0800
 204
 205     Merge tag 'frotz-for-xyzzy' of example.com:/git/froboz.git/
 206
 207     Completed frotz feature
 208
 209     * tag 'frotz-for-xyzzy' (100 commits)
 210       Add tests and documentation for frotz
 211       ...
 212------------
 213
 214There is no need for the auditor to explicitly fetch the contributor's
 215signature, or to even be aware of what tag(s) the contributor and integrator
 216used to communicate the signature.  All the required information is recorded
 217as part of the merge commit.