|
| 1 | +From: Junio C Hamano < [email protected]> |
| 2 | +Date: Tue, 17 Jan 2011 13:00:00 -0800 |
| 3 | +Subject: Using signed tag in pull requests |
| 4 | +Abstract: 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. |
| 8 | +Content-type: text/asciidoc |
| 9 | + |
| 10 | +Using signed tag in pull requests |
| 11 | +================================= |
| 12 | + |
| 13 | +A typical distributed workflow using Git is for a contributor to fork a |
| 14 | +project, build on it, publish the result to her public repository, and ask |
| 15 | +the "upstream" person (often the owner of the project where she forked |
| 16 | +from) to pull from her public repository. Requesting such a "pull" is made |
| 17 | +easy by the `git request-pull` command. |
| 18 | + |
| 19 | +Earlier, 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 | + |
| 31 | +followed by a shortlog of the changes and a diffstat. |
| 32 | + |
| 33 | +The request was for a branch name (e.g. `for-xyzzy`) in the public |
| 34 | +repository of the contributor, and even though it stated where the |
| 35 | +contributor forked her work from, the message did not say anything about |
| 36 | +the commit to expect at the tip of the for-xyzzy branch. If the site that |
| 37 | +hosts the public repository of the contributor cannot be fully trusted, it |
| 38 | +was unnecessarily hard to make sure what was pulled by the integrator was |
| 39 | +genuinely what the contributor had produced for the project. Also there |
| 40 | +was no easy way for third-party auditors to later verify the resulting |
| 41 | +history. |
| 42 | + |
| 43 | +Starting from Git release v1.7.9, a contributor can add a signed tag to |
| 44 | +the commit at the tip of the history and ask the integrator to pull that |
| 45 | +signed tag. When the integrator runs `git pull`, the signed tag is |
| 46 | +automatically verified to assure that the history is not tampered with. |
| 47 | +In addition, the resulting merge commit records the content of the signed |
| 48 | +tag, so that other people can verify that the branch merged by the |
| 49 | +integrator was signed by the contributor, without fetching the signed tag |
| 50 | +used to validate the pull request separately and keeping it in the refs |
| 51 | +namespace. |
| 52 | + |
| 53 | +This document describes the workflow between the contributor and the |
| 54 | +integrator, using Git v1.7.9 or later. |
| 55 | + |
| 56 | + |
| 57 | +A contributor or a lieutenant |
| 58 | +----------------------------- |
| 59 | + |
| 60 | +After preparing her work to be pulled, the contributor uses `git tag -s` |
| 61 | +to 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 | + |
| 69 | +Note that this example uses the `-m` option to create a signed tag with |
| 70 | +just a one-liner message, but this is for illustration purposes only. It |
| 71 | +is advisable to compose a well-written explanation of what the topic does |
| 72 | +to justify why it is worthwhile for the integrator to pull it, as this |
| 73 | +message will eventually become part of the final history after the |
| 74 | +integrator responds to the pull request (as we will see later). |
| 75 | + |
| 76 | +Then she pushes the tag out to her public repository: |
| 77 | + |
| 78 | +------------ |
| 79 | + $ git push example.com:/git/froboz.git/ +frotz-for-xyzzy |
| 80 | +------------ |
| 81 | + |
| 82 | +There is no need to push the `work` branch or anything else. |
| 83 | + |
| 84 | +Note 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 |
| 86 | +contributor may want to reuse a signed tag with the same name after the |
| 87 | +previous pull request has already been responded to. |
| 88 | + |
| 89 | +The 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 | + |
| 95 | +The 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 | + |
| 103 | +The 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 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 | + |
| 123 | +followed by a shortlog of the changes and a diffstat. Comparing this with |
| 124 | +the earlier illustration of the output from the traditional `git request-pull` |
| 125 | +command, 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 | + |
| 131 | +The latter is why the contributor would want to justify why pulling her |
| 132 | +work is worthwhile when creating the signed tag. The contributor then |
| 133 | +opens her favorite MUA, reads msg.txt, edits and sends it to her upstream |
| 134 | +integrator. |
| 135 | + |
| 136 | + |
| 137 | +Integrator |
| 138 | +---------- |
| 139 | + |
| 140 | +After receiving such a pull request message, the integrator fetches and |
| 141 | +integrates the tag named in the request, with: |
| 142 | + |
| 143 | +------------ |
| 144 | + $ git pull example.com:/git/froboz.git/ frotz-for-xyzzy |
| 145 | +------------ |
| 146 | + |
| 147 | +This operation will always open an editor to allow the integrator to fine |
| 148 | +tune the commit log message when merging a signed tag. Also, pulling a |
| 149 | +signed tag will always create a merge commit even when the integrator does |
| 150 | +not have any new commit since the contributor's work forked (i.e. 'fast |
| 151 | +forward'), so that the integrator can properly explain what the merge is |
| 152 | +about and why it was made. |
| 153 | + |
| 154 | +In 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 < [email protected]>" |
| 162 | +------------ |
| 163 | + |
| 164 | +Notice that the message recorded in the signed tag "Completed frotz |
| 165 | +feature" appears here, and again that is why it is important for the |
| 166 | +contributor to explain her work well when creating the signed tag. |
| 167 | + |
| 168 | +As usual, the lines commented with `#` are stripped out. The resulting |
| 169 | +commit records the signed tag used for this validation in a hidden field |
| 170 | +so that it can later be used by others to audit the history. There is no |
| 171 | +need for the integrator to keep a separate copy of the tag in his |
| 172 | +repository (i.e. `git tag -l` won't list the `frotz-for-xyzzy` tag in the |
| 173 | +above example), and there is no need to publish the tag to his public |
| 174 | +repository, either. |
| 175 | + |
| 176 | +After the integrator responds to the pull request and her work becomes |
| 177 | +part of the permanent history, the contributor can remove the tag from |
| 178 | +her public repository, if she chooses, in order to keep the tag namespace |
| 179 | +of her public repository clean, with: |
| 180 | + |
| 181 | +------------ |
| 182 | + $ git push example.com:/git/froboz.git :frotz-for-xyzzy |
| 183 | +------------ |
| 184 | + |
| 185 | + |
| 186 | +Auditors |
| 187 | +-------- |
| 188 | + |
| 189 | +The `--show-signature` option can be given to `git log` or `git show` and |
| 190 | +shows the verification status of the embedded signed tag in merge commits |
| 191 | +created when the integrator responded to a pull request of a signed tag. |
| 192 | + |
| 193 | +A 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 < [email protected]>" |
| 201 | + Merge: 406da78 703f05a |
| 202 | + Author: Inte Grator < [email protected]> |
| 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 | + |
| 214 | +There is no need for the auditor to explicitly fetch the contributor's |
| 215 | +signature, or to even be aware of what tag(s) the contributor and integrator |
| 216 | +used to communicate the signature. All the required information is recorded |
| 217 | +as part of the merge commit. |
0 commit comments