Mercurial 勉強中 (4) - branch と heads

Mercurial には branch という概念があります。これは Subversionsvn cp にて能動的に利用する branch とは違って,システムで用意されている機能です。なので,Subversion における branch(es) のことはスッパリ忘れてください。

ややこしいのは,Mercurial には branch をサポートするためにいくつかの機構があり,それを同じ「branch」という用語で呼んでいることです。ざっくり書くと下記の 3 種類があります(⇒What are branches, merges, heads, and the tip? - FAQ - Mercurial, Branch - Mercurial)。

  • 複数レポジトリによる概念的な branch
  • unnamed branch(別 changeset を元として派生することで生ずる)
  • named branch

今回は unnamed branch について話を絞ります。

branch とは

branch とは,同じコードセットで開発を行っていきつつも,いくつか異なる派生物をメンテナンスしていきたいときに欲しくなる概念です。

たとえば,

  • 最新開発ツリー(development branch)
  • Version 1.0 安定化 branch
  • Version 2.0 安定化 branch

などに分けて開発したり,

  • 東京営業所用カスタマイズ
  • 大阪営業所用カスタマイズ

などを用意するときに,便利です。

Mercurial での (unnamed) branch

Mercurial では単一のレポジトリ内に複数の branch をもつことができます。



この例では,

  • 一つのレポジトリが 6 つの branch に分かれて履歴管理が行われている/いたこと
  • うち 3 つの branch は他の branch に merge されたため,レポジトリとして active な branch としてはみなされていないこと
  • よって merge されていない branch として 3 つの branch が存在すること

を示しています。

この未 merge な branch の最終 changeset を heads と呼ぶのですが,これだけではその概念がわかりにくいので changeset について説明します。

changeset とは

リビジョンを changeset 単位で管理している,というのは Subversion と同じなので省略します。

changeset と branch, heads

Mercurial での branch というのは,実際には各 changeset の持っている「属性」のようなものです*1

先ほどの branch の図を changeset の時系列沿いに表記したものを下記に示します。

ちょっと状況が異なる図なのですが,イメージはわかると思います。

  • changeset #1, #2, #3 は changeset #0 を元として作成された
  • changeset #5 を changeset #7 に merge した
    • このため,changeset #2, #5 の属する branch は inactive となった
  • changeset #6 は,どこにも merge していない
    • merge していない変更点のある changeset を heads と呼ぶ
    • レポジトリにどのような heads があるのかは hg heads コマンドにて確認できる

branch (changeset) は必ずしも merge しなくてはいけないわけではありません。

先ほどあげた例のように,あえて「大阪営業所用カスタマイズ」として changeset #3, #6 のラインを主体的に残すと,概念的な branch と為すことができるわけです。

branch が使われる・発生する局面

では,複数の branch に分岐するのはどのようなことが trigger となるのでしょうか。

  1. 旧 changeset revision から派生して開発を行った場合
  2. 明示的に branch を指定して branch を生成した場合(named branch)
  3. 他 repository との間で conflict が発生した場合

1. については,実際には 2. のように明示的に branch 名をつけて行うほうがベターなので省略します。2. については Mercurial 勉強中 (6) - named branch と update -C - daily dayflower に書きました。3. については Mercurial 勉強中 (5) - conflict と multiple heads, merge - daily dayflower に書きました。

*1:もっと具体的にいうと,ある changeset が,どの changeset(s) を親にもつのか,ということを示しているだけなんですが。