Skip to content

Commit 11b17af

Browse files
committed
pulling signed tag: add howto document
Signed-off-by: Junio C Hamano <[email protected]>
1 parent b63103e commit 11b17af

File tree

2 files changed

+221
-1
lines changed

2 files changed

+221
-1
lines changed

Documentation/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ ARTICLES += everyday
2020
ARTICLES += git-tools
2121
ARTICLES += git-bisect-lk2009
2222
# with their own formatting rules.
23-
SP_ARTICLES = howto/revert-branch-rebase howto/using-merge-subtree user-manual
23+
SP_ARTICLES = user-manual
24+
SP_ARTICLES += howto/revert-branch-rebase
25+
SP_ARTICLES += howto/using-merge-subtree
26+
SP_ARTICLES += howto/using-signed-tag-in-pull-request
2427
API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technical/api-index.txt, $(wildcard technical/api-*.txt)))
2528
SP_ARTICLES += $(API_DOCS)
2629
SP_ARTICLES += technical/api-index
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
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

Comments
 (0)