Gitを使用する一般的な分散ワークフローは、貢献者がプロジェクトをフォークし、プロジェクトを構築し、結果をパブリックリポジトリに公開し、「上流」の人(多くの場合、フォーク元のプロジェクトの所有者)に、貢献者のパブリックリポジトリからプルするように依頼することです。 このような「プル」のリクエストは、 git request-pull コマンドで簡単に行えます。

以前は、典型的なプルリクエストは以下ように始まっていたかもしれません:

 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

これに変更のショートログとdiffstatが続きます。

そのリクエストは、貢献者の公開リポジトリにあるブランチ名(例: for-xyzzy)で、そして、貢献者がどこからブツをフォークしたかを述べていたとしても、メッセージには、 for-xyzzy ブランチの先端で期待されるコミットについては何も書かれていませんでした。 貢献者公開リポジトリをホストするサイトが完全に信頼できない場合は、インテグレーター(統合者)によってプルされたブツが、純粋にプロジェクトのために貢献者が作成したものであるかどうかを確かめるのは不必要に困難でした。 また、第三者の監査人(auditors)が後で結果の履歴を検証(verify)する簡単な方法はありませんでした。

Gitリリースv1.7.9以降、貢献者は、履歴の先端にあるコミットに署名付きタグを追加し、インテグレーター(統合者)にその署名付きタグをプルするように依頼できます。 インテグレーター(統合者)が git pull を実行すると、署名されたタグが自動的に検証され、履歴が改ざんされていないことが保証されます。 さらに、結果のマージコミットは、署名されたタグの内容を記録するため、他の人々は、インテグレーター(統合者)によってマージされたブランチが貢献者によって署名されたことを確認できるように、プルリクエストの検証に使用される署名付きタグを個別にフェッチして、refs名前空間に保持する必要はありません。

このドキュメントでは、 Git v1.7.9 以降を使用した、貢献者とインテグレーター(統合者)間のワークフローについて説明します。

貢献者(contributor)またはサブリーダー(lieutenant)

プルするモノが準備できたら、貢献者は git tag- s を使用して署名付きタグを作成します:

 $ git checkout work
 $ ... "git pull" from sublieutenants, "git commit" your own work ...
 $ git tag -s -m "Completed frotz feature" frotz-for-xyzzy work

注意: この例では、 -m オプションを使用して、1行メッセージのみを含む署名付きタグを作成していますが、これは操作説明のための簡略です。 インテグレーター(統合者)がプルリクエストに応答した後、このメッセージは最終的に最終的な履歴の一部になるため、このメッセージは、インテグレーター(統合者)がプルする価値がある理由を正当化するために、トピックが何をするかについて詳しく書かれた説明を作成することをお勧めします(後述します)。

次に、彼女はタグを自分の公開リポジトリにプッシュします:

 $ git push example.com:/git/froboz.git/ +frotz-for-xyzzy

work ブランチなどをプッシュする必要はありません。

上記のコマンドラインでは、 +frotz-for-xyzzy の先頭にプラス記号を使用して、タグの更新を強制できるようにしています。 同一の寄稿者が、以前のプルリクエストがすでに応答された後、同一の名前の署名されたタグを再利用したい場合があるためです。

次に、貢献者は「プル」を要求するメッセージを準備します:

 $ git request-pull v3.2 example.com:/git/froboz.git/ frotz-for-xyzzy >msg.txt

引数は以下のとおりです:

  1. インテグレーター(統合者)のコミットのバージョンは、貢献者の作業に基づいています

  2. 貢献者がプルしたいものをプッシュしたリポジトリのURL

  3. 貢献者がプルしたいタグの名前(以前は、ここにブランチ名しか記述できませんでした)。

結果のファイル msg.txt は以下のようになります:

 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
 -----------------------------------------------

これに変更のショートログとdiffstatが続きます。 先程の出力例の、従来の git request-pull コマンドからの出力と比較すると、読者は以下のことに気付くでしょう:

  1. 期待する先端コミットがインテグレーター(統合者)に示されます

  2. 署名されたタグメッセージは、ショートログの前の破線(dashed lines)の間に目立つように表示されます。

後者は、なぜ、署名入りタグを作成して貢献者が自分の作品をプルする価値があるか正当化したかったかです。 その後、貢献者はお気に入りのMUAを開き、 msg.txt を読み取り、編集して、上流インテグレーター(統合者)に送信します。

Integrator

以下のようなプルリクエストメッセージを受信後、インテグレーター(統合者)はリクエストで指定されたタグをフェッチして統合します:

 $ git pull example.com:/git/froboz.git/ tags/frotz-for-xyzzy

この操作は常にエディターを開き、インテグレーター(統合者)が署名されたタグをマージするときにコミットログメッセージを微調整できるようにします。 また、署名されたタグをプルすると、コントリビューターの作業がフォークされてからインテグレーターに新しいコミットがない場合(つまり、「早送り」の場合)でも、常にマージコミットが作成され、インテグレーター(統合者)がマージの内容とマージが行われた理由を適切に説明できるようにします。

エディター内では、インテグレーター(統合者)は以下のように表示されます:

 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>"

署名されたタグ「Completed frotz feature」に記録されたメッセージがここに表示されることに注意してください。そのため、署名されたタグを作成するときに、貢献者が自分の作業をうまく説明することが重要です。

いつものように、 # でコメントされた行は削除されます。 結果のコミットは、この検証に使用された署名付きタグを非表示フィールドに記録し、後で他のユーザーが履歴を監査するために使用できるようにします。 インテグレーター(統合者)が自分のリポジトリにタグの個別のコピーを保持する必要はなく(つまり、 git tag -l は、上記の例の frotz-for-xyzzy タグ をリストしません)、タグを自分の公開リポジトリに公開する必要もありません。

インテグレーター(統合者)がプルリクエストに応答し、貢献者の作業が永続的な履歴の一部になった後、 貢献者は自分の公開リポジトリからタグを削除できます。 貢献者が自分の公開リポジトリからタグを削除する選択をした場合、貢献者のパブリックリポジトリのタグ名前空間をクリーンに保つために、以下のようにします:

 $ git push example.com:/git/froboz.git :frotz-for-xyzzy

監査人(Auditors)

--show-signature オプションは git log または git show で指定でき、インテグレーター(統合者)が署名付きタグのプルリクエストに応答したときに作成されたマージコミットで埋め込まれた署名付きタグの検証ステータス(verification status)を表示します。

git show --show-signature からの典型的な出力は、以下のようになります:

 $ 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
       ...

監査人(auditor)が貢献者の署名を明示的に取得したり、貢献者とインテグレーター(統合者)が署名の伝達に使用したタグを認識したりする必要はありません。 必要なすべての情報は、マージコミットの一部として記録されます。