Bazaarの哲学

Bazaarを完全に理解する

Bazaarは多くの点で他のVCSに似ていますが、最初見たときに必ずしも明らかではない大きな違いがいくつかあります。 このセクションでは Bazaarを”grok”するため、すなわち深く理解するために、 ユーザーが知る必要のあるいくつかの内容の説明を試みます。

注: Bazaarを使うためにこのセクションを十分に理解する必要はありません。 このセクションをさっと読んで後で戻るとよいでしょう。

リビジョン番号を理解する

ブランチのメインラインのすべてのリビジョンは単純に増加する整数を持ちます(最初のコミットは1、10番目のコミットは10などです)。 これによって “私のブランチから10番目のリビジョンを獲得する”、もしくは “リビジョン3050で修正した” という言い方が自然になります。

ブランチにマージされるリビジョンに関しては、ドットつきのバージョンが使われます(たとえば、3112.1.5)。 ドットつきのリビジョン番号は3つの番号を持ちます [1]. 最初の番号はメインのリビジョンの変更の由来を示します。 2番目の番号はブランチのカウンターです。 同じリビジョンから多くのブランチが由来することがあり得るので、それらのブランチはユニークな番号を取得します。 3番目の番号はブランチの開始以降のリビジョン番号です。 たとえば、3112.1.5はリビジョン3112からの最初のブランチで、そのブランチ上の5番目のリビジョンです。

[1]バージョン1.2以前のbzrでは少し異なるアルゴリズムが使われていました。 いくつかの入れ子のブランチはよりシンプルな3つの番号システムではなく追加の番号(たとえば1.1.1.1.1)を取得します。

階層形式の履歴はよいものである

多くの変更が一連のコミットで構成される状況で複数の開発者が変更を投稿するプロジェクトを想像してください。 具体例を示すために、次の事例を考えてみましょう:

  • プロジェクトのトランクのチップはリビジョン100です。
  • Maryは機能Xを配信するために3つの変更を行う
  • Billは機能Yを配信するために4つの変更を行う

開発者が並行して作業して伝統的な集中型のVCSのアプローチを利用する場合、 大抵の場合プロジェクトの履歴は次のようにMaryの変更とBillの変更が交互に混ざります:

107: Add documentation for Y
106: Fix bug found in testing Y
105: Fix bug found in testing X
104: Add code for Y
103: Add documentation for X
102: Add code and tests for X
101: Add tests for Y
100: ...

多くのチームはこのアプローチを利用します。彼らのツールではブランチの作成とマージが難しいからです。 結果として、開発者はトランクからの更新とコミットを頻繁に行い、すべてのコミットを通してそれを広げることで統合の苦痛を最小化します。 望むのであれば、このようにBazaarを使うことができます。 Bazaarは考慮すべき別の方法を提供します。

分散型のVCSツールによって推奨される代替のアプローチは機能ブランチを作り、準備ができたらそれらを統合することです。 この場合、Maryの機能ブランチは次のようになります:

103: Fix bug found in testing X
102: Add documentation for X
101: Add code and tests for X
100: ...

そしてBillのものは次のようになります:

104: Add documentation for Y
103: Fix bug found in testing Y
102: Add code for Y
101: Add tests for Y
100: ...

機能が独立していてリニアな履歴を維持したいのであれば、変更はバッチでトランクにpushされます。 (技術的には、これを行う方法は無数にありますがこの検討内容の範囲を超えます。) 結果の履歴は次のようになります:

107: Fix bug found in testing X
106: Add documentation for X
105: Add code and tests for X
104: Add documentation for Y
103: Fix bug found in testing Y
102: Add code for Y
101: Add tests for Y
100: ...

これを実現するために少し努力が必要な一方で、リビジョンをランダムに織り交ぜるよりもいくつかの利点があります。 よりベターですが、non-linearな履歴を形成してブランチは一緒にマージできます。 結果は次のようになります:

102: Merge feature X
     100.2.3: Fix bug found in testing X
     100.2.2: Add documentation for X
     100.2.1: Add code and tests for X
101: Merge feature Y
     100.1.4: Add documentation for Y
     100.1.3: Fix bug found in testing Y
     100.1.2: Add code for Y
     100.1.1: Add tests for Y
100: ...

もしくは次のようになります:

102: Merge feature X
     100.2.3: Fix bug
     100.2.2: Add documentation
     100.2.1: Add code and tests
101: Merge feature Y
     100.1.4: Add documentation
     100.1.3: Fix bug found in testing
     100.1.2: Add code
     100.1.1: Add tests
100: ...

多くの理由からこれはよいものと考えられます:

  • プロジェクトの履歴を理解するのが楽になります。 関連した変更はクラスターを形成し明確に区切られます。
  • ブランチのメインライン上のコミットだけを見るために履歴を簡単に折りたたむことができます。 (このレベルでは興味のない膨大な数のコミットの代わりに) このようなトランクの履歴を閲覧するとき、高いレベルのコミットだけ見えます。
  • 必要であれば、より簡単に機能の変更を取り消します
  • 継続的インテグレーション(Continuous integration: CI)ツールは マージをメインラインにコミットするためにすべてのテストが合格することを保証するために使われます。 (多くの場合、すべての単独のコミットの後でCIツールの引き金を引くのは適切ではありません。 テストの中には開発の間に失敗するものがあるからです。 実際、テストファーストの追加 - テスト駆動開発(TDD)のスタイル - によってこれが保証されます!)

要約すると、重要な点は次のとおりです:

ブランチを利用してあなたの作業内容を編成する

マージ機能を利用して変更を統合する

順序つきの番号と階層によって履歴を追跡するのが楽になる

それぞれのブランチは履歴の独自のビューを持つ

上述のように、Bazaarは次の内容を区別します:

  • メインラインのリビジョン、すなわちブランチにコミットしたもの
  • マージしたリビジョン、マージをコミットすることで祖先として追加されるもの

それぞれのブランチは効率的に履歴の独自ビューを持ち、すなわち、 異なるブランチは同じリビジョンに異なる”ローカルな”リビジョン番号を与えます。

マージされたリビジョンは常にドットつきのリビジョン番号を入手するのに対して メインラインのリビジョンは常に単独の数字のリビジョン番号が割り当てられます。

上記の例を拡張するためには、Maryが変更を完了させた後でプロジェクトのトランクにマージした後に Maryのブランチのリビジョンの履歴は次のようになります:

104: Merge mainline
     100.2.1: Merge feature Y
     100.1.4: Add documentation
     100.1.3: Fix bug found in testing
     100.1.2: Add code
     100.1.1: Add tests
103: Fix bug found in testing X
102: Add documentation for X
101: Add code and tests for X
100: ...

繰り返しますが、Maryはこの変更を開発するためにステップを見るために彼女の履歴のトップレベルを調べることが簡単になります。 この文脈では、トランクのマージ(とそれを行うことによる衝突の解消)はこのブランチの履歴に関しては単なる1つのステップです。

Bazaarは履歴を変更するのでなければグローバルなリビジョン識別子を変更するのでもないことを覚えておくのは大事です。 本当に望むのであれば常に後者を使用できます。 実際、ブランチのURLをコンテクストとして提供する 限り コミュニケーションをするときに特定のリビジョン番号を使うことができます。 (多くのBazaarのプロジェクトでは、開発者はブランチURLなしでリビジョン番号を交換するとき中心のトランクのブランチをほのめかします)

マージはブランチのリビジョン番号を変更しません。それらはローカルのリビジョン番号を新しくマージしたリビジョンに割り当てるからです。 Bazaarがブランチのリビジョン番号を変更する唯一のときはあなたが明示的に別のブランチをミラーリングするように頼むときです。

注: リビジョンは安定した方法で番号づけされます: 2つのブランチがメインラインで同じリビジョン番号を持つとき、 そのリビジョンの祖先のすべてのリビジョンは同じリビジョン番号を持ちます。 たとえば、AliceとBobのブランチがリビジョン10に一致するのであれば、それらはそれ以前のすべてのリビジョンで一致します。

要約

一般的に、前に示されたアドバイスに従うのであれば - ブランチの中で作業し、連携するためにマージを使う - Bazaarが一般的にあなたが期待することを行うことがわかります。

次の章では、Bazaarを利用したさまざまな方法: もっとも単純なプロジェクト、個人プロジェクトなどを試します。