Merge branch 'rp/apply-cached-with-i-t-a'
[git] / Documentation / howto / using-signed-tag-in-pull-request.txt
1 From: Junio C Hamano <gitster@pobox.com>
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 How to use a 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 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
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/ tags/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 <nitfol@example.com>"
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 <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
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.