章 ▼ 第2版

5.1 分散Git - 分散ワークフロー

開発者全員がコードを共有するための中央拠点としてリモートGitリポジトリがセットアップされ、ローカルワークフローにおける基本的なGitコマンドにも慣れてきたところで、Gitが提供する分散ワークフローの一部をどのように活用するかを見ていきます。

この章では、分散環境においてGitを貢献者および統合者としてどのように扱うかを見ていきます。つまり、プロジェクトにコードをうまく貢献し、あなたとプロジェクトのメンテナ双方にとって可能な限り簡単にする方法を学びます。また、多数の開発者が貢献するプロジェクトをうまく維持管理する方法についても学びます。

分散ワークフロー

集中型バージョン管理システム (CVCS) とは対照的に、Gitの分散型という性質は、開発者がプロジェクトで共同作業を行う方法において、はるかに柔軟な対応を可能にします。集中型システムでは、すべての開発者が中央ハブとほぼ等しく連携するノードとなります。しかしGitでは、すべての開発者がノードでもありハブでもある可能性があります。つまり、すべての開発者が他のリポジトリにコードを貢献することもできれば、他の開発者が作業の基盤とし、貢献できる公開リポジトリを維持することもできるのです。これは、あなたのプロジェクトやチームにとって、非常に幅広いワークフローの可能性をもたらします。そのため、この柔軟性を活用した一般的なパラダイムをいくつか取り上げます。各設計の長所と短所について説明します。単一のものを選択して使用することも、それぞれの機能を組み合わせて使用することもできます。

集中型ワークフロー

集中型システムでは、一般的に単一のコラボレーションモデル、すなわち集中型ワークフローが存在します。一つの中央ハブ、つまりリポジトリがコードを受け入れ、全員がそこに自分の作業を同期させます。多数の開発者はそのハブのコンシューマであるノードであり、その集中型ロケーションと同期します。

Centralized workflow
図53. 集中型ワークフロー

これは、2人の開発者がハブからクローンして両方が変更を行った場合、最初に変更をプッシュした開発者は問題なく作業を進められることを意味します。2番目の開発者は、最初の開発者の変更を上書きしないように、自分の変更をプッシュする前に最初の開発者の作業をマージする必要があります。この概念は、GitにおいてもSubversion(または任意のCVCS)と同様に当てはまり、このモデルはGitで完全に機能します。

あなたの会社やチームですでに集中型ワークフローに慣れている場合、Gitでもそのワークフローを簡単に継続して使用できます。単一のリポジトリをセットアップし、チームの全員にプッシュアクセスを与えるだけです。Gitはユーザーが互いに上書きすることを許可しません。

例えば、ジョンとジェシカが同時に作業を開始したとします。ジョンは変更を完了してサーバーにプッシュします。その後、ジェシカは自分の変更をプッシュしようとしますが、サーバーはそれを拒否します。彼女はノンファストフォワードの変更をプッシュしようとしており、フェッチしてマージするまではそれができないと告げられます。このワークフローは、多くの人が慣れ親しんでおり、使いやすいパラダイムであるため、多くの人にとって魅力的です。

これは小規模チームに限定されません。Gitのブランチモデルを使えば、何百人もの開発者が同時に数十ものブランチを通じて単一のプロジェクトでうまく作業することが可能です。

統合マネージャーワークフロー

Gitでは複数のリモートリポジトリを持つことができるため、各開発者が自身の公開リポジトリへの書き込みアクセス権と、他のすべての開発者のリポジトリへの読み取りアクセス権を持つワークフローが可能です。このシナリオには、多くの場合、「公式」プロジェクトを表す標準リポジトリが含まれます。そのプロジェクトに貢献するには、プロジェクトの自身の公開クローンを作成し、そこにあなたの変更をプッシュします。その後、メインプロジェクトのメンテナに変更をプルするようリクエストを送信できます。メンテナは、あなたのリポジトリをリモートとして追加し、変更をローカルでテストし、自身のブランチにマージし、自身のリポジトリにプッシュし直すことができます。このプロセスは以下の通りです(統合マネージャーワークフローを参照)。

  1. プロジェクトのメンテナは、自分の公開リポジトリにプッシュします。

  2. 貢献者はそのリポジトリをクローンし、変更を加えます。

  3. 貢献者は自身の公開コピーにプッシュします。

  4. 貢献者はメンテナに、変更をプルするように依頼するメールを送信します。

  5. メンテナは、貢献者のリポジトリをリモートとして追加し、ローカルでマージします。

  6. メンテナは、マージした変更をメインリポジトリにプッシュします。

Integration-manager workflow
図54. 統合マネージャーワークフロー

これは、GitHubやGitLabのようなハブベースのツールでは非常に一般的なワークフローです。そこでは、プロジェクトをフォークし、フォークしたリポジトリに変更をプッシュして、誰もがそれを見られるようにするのが簡単です。このアプローチの主な利点の一つは、あなたが作業を継続でき、メインリポジトリのメンテナがいつでもあなたの変更をプルできることです。貢献者は、プロジェクトが自分の変更を取り込むのを待つ必要はありません。各当事者が自分のペースで作業できます。

独裁者と補佐官ワークフロー

これは、複数リポジトリワークフローの一種です。一般的に、何百人もの共同作業者がいる巨大なプロジェクトで使用されます。有名な例としては、Linuxカーネルがあります。様々な統合マネージャーがリポジトリの特定の部分を担当しており、彼らは補佐官と呼ばれます。すべての補佐官には、慈悲深い独裁者として知られる一人の統合マネージャーがいます。慈悲深い独裁者は、自分のディレクトリから、すべての共同作業者がプルする必要がある参照リポジトリにプッシュします。このプロセスは以下の通りです(慈悲深い独裁者ワークフローを参照)。

  1. 通常の開発者は、自分のトピックブランチで作業し、その作業をmasterの上にリベースします。masterブランチとは、独裁者がプッシュする参照リポジトリのブランチのことです。

  2. 補佐官は開発者のトピックブランチを自身のmasterブランチにマージします。

  3. 独裁者は、補佐官のmasterブランチを独裁者のmasterブランチにマージします。

  4. 最後に、独裁者はそのmasterブランチを参照リポジトリにプッシュし、他の開発者がそれにリベースできるようにします。

Benevolent dictator workflow
図55. 慈悲深い独裁者ワークフロー

この種のワークフローは一般的ではありませんが、非常に大規模なプロジェクトや、階層の深い環境で役立つことがあります。これにより、プロジェクトリーダー(独裁者)は作業の大部分を委任し、統合する前に複数の地点でコードの大きなサブセットを収集することができます。

ソースコードブランチを管理するためのパターン

注記

マーティン・ファウラーは「ソースコードブランチを管理するためのパターン」というガイドを作成しました。このガイドは、すべての一般的なGitワークフローを網羅し、それらをいつどのように使用するかを説明しています。また、高頻度と低頻度の統合を比較するセクションもあります。

ワークフローのまとめ

これらはGitのような分散システムで可能な、一般的に使用されるワークフローのいくつかですが、あなたの特定の現実のワークフローに合わせて多くのバリエーションが可能であることがわかるでしょう。あなたにとってどのワークフローの組み合わせが機能するかを(願わくば)判断できるようになったところで、さまざまなフローを構成する主要な役割を達成するためのより具体的な例をいくつか説明します。次のセクションでは、プロジェクトに貢献するためのいくつかの一般的なパターンについて学びます。

scroll-to-top