Git
Chapters ▾ 2nd Edition

5.1 Git での分散作業 - 分散作業の流れ

リモート Git リポジトリを用意し、すべての開発者がコードを共有できるようになりました。また、ローカル環境で作業をする際に使う基本的な Git コマンドについても身についたことでしょう。次に、Git を使った分散作業の流れを見ていきましょう。

本章では、Git を使った分散環境での作業の流れを説明します。 自分のコードをプロジェクトに提供する方法、そしてプロジェクトのメンテナーと自分の両方が作業を進めやすくする方法、そして多数の開発者からの貢献を受け入れるプロジェクトを運営する方法などを扱います。

分散作業の流れ

中央管理型のバージョン管理システム (Centralized Version Control System: CVCS) とは違い、Git は分散型だという特徴があります。この特徴を生かすと、プロジェクトの開発者間での共同作業をより柔軟に行えるようになります。 中央管理型のシステムでは、個々の開発者は中央のハブに対するノードという位置づけとなります。 しかし Git では、各開発者はノードであると同時にハブにもなり得ます。つまり、誰もが他のリポジトリに対してコードを提供することができ、誰もが公開リポジトリを管理して他の開発者の作業を受け入れることもできるということです。 これは、みなさんのプロジェクトや開発チームでの作業の流れにさまざまな可能性をもたらします。本章では、この柔軟性を生かすいくつかの実例を示します。 それぞれについて、利点だけでなく想定される弱点についても扱うので、適宜取捨選択してご利用ください。

中央集権型のワークフロー

中央管理型のシステムでは共同作業の方式は一つだけです。それが中央集権型のワークフローです。 これは、中央にある一つのハブ (リポジトリ) がコードを受け入れ、他のメンバー全員がそこに作業内容を同期させるという流れです。 多数の開発者がハブにつながるノードとなり、作業を一か所に集約します。

中央集権型のワークフロー
Figure 53. 中央集権型のワークフロー

二人の開発者がハブからのクローンを作成して個々に変更をした場合、最初の開発者がそれをプッシュするのは特に問題なくできます。 もう一人の開発者は、まず最初の開発者の変更をマージしてからサーバーへのプッシュを行い、最初の開発者の変更を消してしまわないようにします。 この考え方は、Git 上でも Subversion (あるいはその他の CVCS) と同様に生かせます。そしてこの方式は Git でも完全に機能します。

小規模なチームに所属していたり、組織内で既に中央集権型のワークフローになじんでいたりなどの場合は、Git でその方式を続けることも簡単です。 リポジトリをひとつ立ち上げて、チームのメンバー全員がそこにプッシュできるようにすればいいのです。Git は他のユーザーの変更を上書きしてしまうことはありません。 たとえば、John と Jessica が作業を一斉に始めたとしましょう。 先に作業が終わった John が、変更をサーバーにプッシュします。 次に、Jessica が変更をプッシュしようとすると、サーバー側でそのプッシュは拒否されます。 そして Jessica は、直接プッシュすることはできないのでまずは変更内容をマージする必要があることを Git のエラーメッセージから気づきます。 この方式は多くの人にとって魅力的なものでしょう。これまでにもなじみのある方式だし、今までそれでうまくやってきたからです。

また、この例は小規模なチームに限った話ではありません。Git のブランチモデルを用いてひとつのプロジェクト上にたくさんのブランチを作れば、何百人もの開発者が同時並行で作業を進めることだってできるのです。

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

Git では複数のリモートリポジトリを持つことができるので、書き込み権限を持つ公開リポジトリを各自が持ち、他のメンバーからは読み込みのみのアクセスを許可するという方式をとることもできます。 この方式には、「公式」プロジェクトを表す公式なリポジトリも含みます。 このプロジェクトの開発に参加するには、まずプロジェクトのクローンを自分用に作成し、変更はそこにプッシュします。 次に、メインプロジェクトのメンテナーに「変更を取り込んでほしい」とお願いします。 メンテナーはあなたのリポジトリをリモートに追加し、変更を取り込んでマージします。そしてその結果をリポジトリにプッシュするのです。 この作業の流れは次のようになります ( 統合マネージャー型のワークフロー を参照ください)。

  1. プロジェクトのメンテナーが公開リポジトリにプッシュする

  2. 開発者がそのリポジトリをクローンし、変更を加える

  3. 開発者が各自の公開リポジトリにプッシュする

  4. 開発者がメンテナーに「変更を取り込んでほしい」というメールを送る

  5. メンテナーが開発者のリポジトリをリモートに追加し、それをマージする

  6. マージした結果をメンテナーがメインリポジトリにプッシュする

統合マネージャー型のワークフロー
Figure 54. 統合マネージャー型のワークフロー

これは GitHub や GitLab のようなハブ型のツールでよく使われている流れです。プロジェクトを容易にフォークでき、そこにプッシュした内容をみんなに簡単に見てもらえます。 この方式の主な利点の一つは、あなたはそのまま開発を続行し、メインリポジトリのメンテナーはいつでも好きなタイミングで変更を取り込めるということです。 変更を取り込んでもらえるまで作業を止めて待つ必要はありません。自分のペースで作業を進められるのです。

独裁者と副官型のワークフロー

これは、複数リポジトリ型のワークフローのひとつです。 何百人もの開発者が参加するような巨大なプロジェクトで採用されています。有名どころでは Linux カーネルがこの方式です。 統合マネージャーを何人も用意し、それぞれにリポジトリの特定の部分を担当させます。彼らは副官 (lieutenant) と呼ばれます。 そしてすべての副官をまとめる統合マネージャーが「慈悲深い独裁者 (benevalent dictator)」です。 独裁者のリポジトリが基準リポジトリとなり、すべてのメンバーはこれをプルします。 この作業の流れは次のようになります ( 慈悲深い独裁者型のワークフロー を参照ください)。

  1. 一般の開発者はトピックブランチ上で作業を進め、master の先頭にリベースする。独裁者の master ブランチがマスターとなる

  2. 副官が各開発者のトピックブランチを自分の master ブランチにマージする

  3. 独裁者が各副官の master ブランチを自分の master ブランチにマージする

  4. 独裁者が自分の master をリポジトリにプッシュし、他のメンバーがリベースできるようにする

慈悲深い独裁者型のワークフロー
Figure 55. 慈悲深い独裁者型のワークフロー

この手のワークフローはあまり一般的ではありませんが、大規模なプロジェクトや高度に階層化された環境では便利です。 プロジェクトリーダー (独裁者) が大半の作業を委譲し、サブセット単位である程度まとまってからコードを統合することができるからです。

ワークフローのまとめ

Git のような分散システムでよく使われるワークフローの多くは、実社会での何らかのワークフローにあてはめて考えることができます。 これで、どのワークフローがあなたに合うかがわかったことでしょう (ですよね?)。 次は、より特化した例をあげて個々のフローを実現する方法を見ていきましょう。