You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
8.1 KiB
217 lines
8.1 KiB
From: Junio C Hamano <gitster@pobox.com> |
|
Date: Tue, 17 Jan 2011 13:00:00 -0800 |
|
Subject: Using signed tag in pull requests |
|
Abstract: Beginning v1.7.9, a contributor can push a signed tag to her |
|
publishing repository and ask her integrator to pull it. This assures the |
|
integrator that the pulled history is authentic and allows others to |
|
later validate it. |
|
Content-type: text/asciidoc |
|
|
|
How to use a signed tag in pull requests |
|
======================================== |
|
|
|
A typical distributed workflow using Git is for a contributor to fork a |
|
project, build on it, publish the result to her public repository, and ask |
|
the "upstream" person (often the owner of the project where she forked |
|
from) to pull from her public repository. Requesting such a "pull" is made |
|
easy by the `git request-pull` command. |
|
|
|
Earlier, a typical pull request may have started like this: |
|
|
|
------------ |
|
The following changes since commit 406da78032179...: |
|
|
|
Froboz 3.2 (2011-09-30 14:20:57 -0700) |
|
|
|
are available in the Git repository at: |
|
|
|
example.com:/git/froboz.git for-xyzzy |
|
------------ |
|
|
|
followed by a shortlog of the changes and a diffstat. |
|
|
|
The request was for a branch name (e.g. `for-xyzzy`) in the public |
|
repository of the contributor, and even though it stated where the |
|
contributor forked her work from, the message did not say anything about |
|
the commit to expect at the tip of the for-xyzzy branch. If the site that |
|
hosts the public repository of the contributor cannot be fully trusted, it |
|
was unnecessarily hard to make sure what was pulled by the integrator was |
|
genuinely what the contributor had produced for the project. Also there |
|
was no easy way for third-party auditors to later verify the resulting |
|
history. |
|
|
|
Starting from Git release v1.7.9, a contributor can add a signed tag to |
|
the commit at the tip of the history and ask the integrator to pull that |
|
signed tag. When the integrator runs `git pull`, the signed tag is |
|
automatically verified to assure that the history is not tampered with. |
|
In addition, the resulting merge commit records the content of the signed |
|
tag, so that other people can verify that the branch merged by the |
|
integrator was signed by the contributor, without fetching the signed tag |
|
used to validate the pull request separately and keeping it in the refs |
|
namespace. |
|
|
|
This document describes the workflow between the contributor and the |
|
integrator, using Git v1.7.9 or later. |
|
|
|
|
|
A contributor or a lieutenant |
|
----------------------------- |
|
|
|
After preparing her work to be pulled, the contributor uses `git tag -s` |
|
to create a signed tag: |
|
|
|
------------ |
|
$ git checkout work |
|
$ ... "git pull" from sublieutenants, "git commit" your own work ... |
|
$ git tag -s -m "Completed frotz feature" frotz-for-xyzzy work |
|
------------ |
|
|
|
Note that this example uses the `-m` option to create a signed tag with |
|
just a one-liner message, but this is for illustration purposes only. It |
|
is advisable to compose a well-written explanation of what the topic does |
|
to justify why it is worthwhile for the integrator to pull it, as this |
|
message will eventually become part of the final history after the |
|
integrator responds to the pull request (as we will see later). |
|
|
|
Then she pushes the tag out to her public repository: |
|
|
|
------------ |
|
$ git push example.com:/git/froboz.git/ +frotz-for-xyzzy |
|
------------ |
|
|
|
There is no need to push the `work` branch or anything else. |
|
|
|
Note that the above command line used a plus sign at the beginning of |
|
`+frotz-for-xyzzy` to allow forcing the update of a tag, as the same |
|
contributor may want to reuse a signed tag with the same name after the |
|
previous pull request has already been responded to. |
|
|
|
The contributor then prepares a message to request a "pull": |
|
|
|
------------ |
|
$ git request-pull v3.2 example.com:/git/froboz.git/ frotz-for-xyzzy >msg.txt |
|
------------ |
|
|
|
The arguments are: |
|
|
|
. the version of the integrator's commit the contributor based her work on; |
|
. the URL of the repository, to which the contributor has pushed what she |
|
wants to get pulled; and |
|
. the name of the tag the contributor wants to get pulled (earlier, she could |
|
write only a branch name here). |
|
|
|
The resulting msg.txt file begins like so: |
|
|
|
------------ |
|
The following changes since commit 406da78032179...: |
|
|
|
Froboz 3.2 (2011-09-30 14:20:57 -0700) |
|
|
|
are available in the Git repository at: |
|
|
|
example.com:/git/froboz.git tags/frotz-for-xyzzy |
|
|
|
for you to fetch changes up to 703f05ad5835c...: |
|
|
|
Add tests and documentation for frotz (2011-12-02 10:02:52 -0800) |
|
|
|
----------------------------------------------- |
|
Completed frotz feature |
|
----------------------------------------------- |
|
------------ |
|
|
|
followed by a shortlog of the changes and a diffstat. Comparing this with |
|
the earlier illustration of the output from the traditional `git request-pull` |
|
command, the reader should notice that: |
|
|
|
. The tip commit to expect is shown to the integrator; and |
|
. The signed tag message is shown prominently between the dashed lines |
|
before the shortlog. |
|
|
|
The latter is why the contributor would want to justify why pulling her |
|
work is worthwhile when creating the signed tag. The contributor then |
|
opens her favorite MUA, reads msg.txt, edits and sends it to her upstream |
|
integrator. |
|
|
|
|
|
Integrator |
|
---------- |
|
|
|
After receiving such a pull request message, the integrator fetches and |
|
integrates the tag named in the request, with: |
|
|
|
------------ |
|
$ git pull example.com:/git/froboz.git/ tags/frotz-for-xyzzy |
|
------------ |
|
|
|
This operation will always open an editor to allow the integrator to fine |
|
tune the commit log message when merging a signed tag. Also, pulling a |
|
signed tag will always create a merge commit even when the integrator does |
|
not have any new commit since the contributor's work forked (i.e. 'fast |
|
forward'), so that the integrator can properly explain what the merge is |
|
about and why it was made. |
|
|
|
In the editor, the integrator will see something like this: |
|
|
|
------------ |
|
Merge tag 'frotz-for-xyzzy' of example.com:/git/froboz.git/ |
|
|
|
Completed frotz feature |
|
# gpg: Signature made Fri 02 Dec 2011 10:03:01 AM PST using RSA key ID 96AFE6CB |
|
# gpg: Good signature from "Con Tributor <nitfol@example.com>" |
|
------------ |
|
|
|
Notice that the message recorded in the signed tag "Completed frotz |
|
feature" appears here, and again that is why it is important for the |
|
contributor to explain her work well when creating the signed tag. |
|
|
|
As usual, the lines commented with `#` are stripped out. The resulting |
|
commit records the signed tag used for this validation in a hidden field |
|
so that it can later be used by others to audit the history. There is no |
|
need for the integrator to keep a separate copy of the tag in his |
|
repository (i.e. `git tag -l` won't list the `frotz-for-xyzzy` tag in the |
|
above example), and there is no need to publish the tag to his public |
|
repository, either. |
|
|
|
After the integrator responds to the pull request and her work becomes |
|
part of the permanent history, the contributor can remove the tag from |
|
her public repository, if she chooses, in order to keep the tag namespace |
|
of her public repository clean, with: |
|
|
|
------------ |
|
$ git push example.com:/git/froboz.git :frotz-for-xyzzy |
|
------------ |
|
|
|
|
|
Auditors |
|
-------- |
|
|
|
The `--show-signature` option can be given to `git log` or `git show` and |
|
shows the verification status of the embedded signed tag in merge commits |
|
created when the integrator responded to a pull request of a signed tag. |
|
|
|
A typical output from `git show --show-signature` may look like this: |
|
|
|
------------ |
|
$ git show --show-signature |
|
commit 02306ef6a3498a39118aef9df7975bdb50091585 |
|
merged tag 'frotz-for-xyzzy' |
|
gpg: Signature made Fri 06 Jan 2012 12:41:49 PM PST using RSA key ID 96AFE6CB |
|
gpg: Good signature from "Con Tributor <nitfol@example.com>" |
|
Merge: 406da78 703f05a |
|
Author: Inte Grator <xyzzy@example.com> |
|
Date: Tue Jan 17 13:49:41 2012 -0800 |
|
|
|
Merge tag 'frotz-for-xyzzy' of example.com:/git/froboz.git/ |
|
|
|
Completed frotz feature |
|
|
|
* tag 'frotz-for-xyzzy' (100 commits) |
|
Add tests and documentation for frotz |
|
... |
|
------------ |
|
|
|
There is no need for the auditor to explicitly fetch the contributor's |
|
signature, or to even be aware of what tag(s) the contributor and integrator |
|
used to communicate the signature. All the required information is recorded |
|
as part of the merge commit.
|
|
|