各種ファイル形式

GNU arch はファイルシステム中にさまざまな形式のファイル、ディ レクトリを作る。ここでは GNU arch が作るこれらのアイテムの編成や形 式について説明する。

チェンジセット

GNU arch の根幹を支えるデータ構造がチェンジセットであるこ とは繰り返し述べてきた。新しいリビジョンを作るときに GNU arch 内 部で処理されていることは、直前のリビジョンと今回のリビジョンの間 差分をチェンジセットとして求めることだ。求まったチェンジセットを tar で固めてアーカイブに追加すればコミットは完了する。チェンジセッ トは決まった形式のディレクトリとして表現される。以下がその構造だ。

インベントリマップ

チェンジセットの最上位ディレクトリ内には、ファイルとイン ベントリidの対応表がある。変更前ツリー/変更後ツリーの区別、ファ イル/ディレクトリの区別の組み合わせで四つのファイルがある。各 ファイル内はタブで区切られた二つのフィールドからなる。最初がファ イル名(ディレクトリ名)、次が対応するインベントリidである。いず れも sort -k 2 コマンドでソートされていると仮定してよい。

orig-dirs-index

変更前ツリー に存在しているすべてのサブディレクトリとそのインベントリid の対応表

mod-dirs-index

変更後ツリーに 存在しているすべてのサブディレクトリとそのインベントリidの 対応表

orig-files-index

変更前ツリー に存在していたすべての通常ファイルとそのインベントリidの対 応表

mod-files-index

変更後ツリー に存在しているすべての通常ファイルとそのインベントリidの対 応表

テーブル中の「通常ファイル」とは「ディレクトリ以外のファ イル」という意味である。つまりシンボリックリンクなども含む。

ディレクトリメタデータ

削除されたディレクトリ、追加されたディレクトリのファイル パーミッションなどを保存するために二つのファイルがある。通常の ファイルについては「ファイルの内容」を保存しなくてはならないの で、そのファイルのパーミッションで表現できるが、ディレクトリは 「ファイルの中身」が存在しないので、ファイルと同じ形式で持つの は無駄だ。そこで変更前、変更後用の二つのファイルに一覧を記録し てある。一行は、[メタデータ]タブ[名前]の形になる。

original-only-dir-metadata

変 更元のみに存在していたディレクトリのパーミッションの一覧

modified-only-dir-metadata

変 更後のみに存在していたディレクトリのパーミッションの一覧

両方のファイルとも、sort -t '<tab>' -k 2 でソートされて いることを仮定してよい。この二つのファイルに記録されるメタデー タは今後の拡張で追加される可能性がある。

削除ファイル、追加ファイル

ディレクトリ以外のファイルで削除されたもの、追加されたも のは、そのままの形で以下の二つのディレクトリに保存される。ファ イルの元ツリー中での相対的なパスは保存される。たとえば、. /foo/bar/baz.txt というファイルが削除された場合には、

./removed-files-archive/foo/bar/baz.txt

という名前のファイルにそっくりそのまま内容が保存される。 保存ファイルのパーミッションも厳密に保存される。

removed-files-archive

変更前ツ リーにのみ存在した全通常ファイルを格納するディレクトリ

new-files-archive

変更後ツリー にのみ存在する全通常ファイルを格納するディレクトリ

パッチファイル

最後に、patches ディレクトについて説明する。チェンジセッ ト最上位にあるこのディレクトリには変更前と変更後の差分に対応し たパッチファイルが保存されている。ファイルの追加や削除がなけれ ば、このディレクトリ内のパッチの情報が最も重要な情報になる。

それぞれのパッチは通常の GNUdiff の unidiff 形式のファイ ルだが、ファイルの内容に対する変更と同時にファイル名称変更があっ た場合には、変換前、変換後のファイル名称は異なる。patches ディ レクトリ配下のすべてのファイルは、常に変換後のファイ ル名を基準にして格納されるという決まりがある。

よく考えると、これは少し奇妙なことだ。なぜなら GNU arch のチェンジセットは可逆な性質があり、変更前、変更後の情報に対し て論理的には完全に同等の関係にあるからだ。しかし実際の表現方法 を見ると、このようにパリティーが変換後に傾いている。これはなぜ だろうか? おそらく実際の利用でのチェンジセットの適用は変換前か ら変換後の方法に向かうことがほとんどであり、このような構成にし ておいたほうが処理が効率化されるのだろう。

patches ディレクトリにある具体的なファイルは以下のような ものである。ただし new_name は今いったように変換後の名前である。 new_name がサブディレクトリにあれば、patches 配下も対応したサ ブディレクトリができるのは remove-files-archive などのディレク トリと同じである。

new_name.link-orig

変更前のシンボリックリンク名を含む

new_name.link-mod

変更後のシンボリックリンク名を含む

new_name.original

変更前のファイル内容をそのまま含む

new_name.modified

変更後のファイル内容をそのまま含む

new_name.patch

変更前・後のファイルの差分を unified 形式で 持つ

new_name.meta-orig

変更前のメタ・データを含む

new_name.meta-mod

変更後のメタ・データを含む

new_name/=dir-meta-orig

変更前のディレクトリ・メタ・データを含む

new_name/=dir-meta-mod

変更後のディレクトリ・メタ・データを含む

チェンジセットの計算はリビジョン間だけではなく、任意のツリー 間に対して行うことができる。リビジョン間のチェンジセットは {arch}サブディレクトリを管理領域として必ず含んでいることに特徴が ある。

チェンジセットに関係してふたつの演算がある。チェンジセット を求める演算と、適用する演算だ。それぞれ tla changeset, tla apply-changeset コマンドに対応する。前者は任意のツリー間に対して 必ず値が求まり成功するが、後者は失敗することもある。これは任意の 数の2乗は必ず計算できるが、その逆の演算である平方根が常にもとま るとは限らないのと似ている。

{arch}管理領域

プロジェクトツリーのルートディレクトリにある{arch}管理領域 直下には以下のようなファイルがある

表 A.1. ファイル一覧

ファイル名F/D説明
++default-versionFtla set-tree-version で設定されるデフォルトバージョ ン名が、A/C--B--V の形で記録されている。
++pristine-treesDプロジェクトツリーに追加されたプリスティンツリー が保存される。このディレクトリに下に更に locked/ と unlocked/ というサブディレクトリが作られ、そこに格納され る。詳しくは tla lock-pristine コマンドを参照のこと。
,,inode-sigsDインベントリスキャンを高速化するためのi-nodeキャッシュ 情報があるディレクトリ。高速化にのみ関係しているので、',,' で始まる名称に従い junk ファイルとみなせる。つまり、常に (そのような場面はほとんどありえないが、とにかく)ディレク トリごと安全に消すことができる。ディレクトリの下には A%C--B--V--R という名前のサブディレクトリがあり、その中 にリビジョンごとのi-nodeキャッシュ情報がある。
.arch-project-treeFこのプロジェクトツリーのバージョン情報が入った通 常ファイル。プロジェクトツリーの形式が今後大きく変わった 場合にはこのファイル内容が区別できるような別の文字列にな ると考えられる。
=tagging-methodFインベントリタグの大域的なタグづ け方法を決めたり、GNU arch が認識する 6種類のファイルタ イプを定義するためのファイル。実際の利用において、{arch} 管理領域中、唯一手で編集されることのあるファイルである。
上記以外のディレクトリDパッチログのためのディレクトリに なる。カテゴリ名として存在する。

上記で、プリスティンツリーの構造は、 ./C/C--B/C--B--V/A/C--B--V--R/ のような構成になる。この最後のサ ブディレクトリの下にプロジェクトツリーのルートにあるツリーと全く 同じ形式のツリーが保存される形になる。ただしプリスティンツリーの プリスティンツリーは存在しない。階層のループが発生してしまうので 自明であろう。

パッチログの構造は、./C/C--B/C--B--V/A/patch-log/R という 形になる。最後の R はリビジョン名をもつ通常ファイルである。

アーカイブ領域

アーカイブ領域は import/commit コマンドなどにより新しくで きたリビジョンの差分情報を格納する場所である。いったん格納された データは永続的に保存され、以後修正が加わることはない。この意味で アーカイブは基本的にはサイズが増加する一方だと言える。例外はリビ ジョンキャッシュ情報で、tla uncacherev コマンドを実行するとアー カイブ中のキャッシュは削除される。もちろんこれはキャッシュの削除 なのでアーカイブの論理的な情報量が減るわけではない。アーカイブは 複数のバージョンから構成され、アーカイブ + バージョン一つの論 理的なバージョン管理単位となり、他のバージョン管理システムで「リ ポジトリ」と呼ばれる単位にほぼ相当する。

表 A.2. ファイル一覧

ファイル名F/D説明
=meta-infoDアーカイブ全体についてのメタ情報が格納されるディ レクトリ。現時点では name, mirror, signed-archive の三つ ファイルが存在しうる。name はこのアーカイブの名前、 mirror はこのアーカイブのミラーとしての名前、 signed-archive はこのアーカイブがサインつきであることを 示すファイルである。
.archive-versionFアーカイブの形式を示すバージョン情報文字列を含む ファイルである。今後の拡張でアーカイブの形式が大きく変わ るような場合にはこの中の文字列が変更になると考えられる。
上記以外のディレクトリDそれぞれカテゴリを示すディレクト リ。この下に実際のアーカイブバージョンが格納される。

アーカイブの際上位ディレクトリの名前は、実際に結びつけられ るアーカイブ名と一致させる必要はなく、任意の名前で作成してよい。 アーカイブ名との関連は =meta-info/name ファイルによって知ること ができるためである。しかし、特に理由がない限りアーカイブ名に一致 したものとすることを勧める。これには tla make-archive コマンドで アーカイブ位置を示すディレクトリの最後の部分をアーカイブ名に一致 させればよい。たとえば:

$ tla make-archive octopus@bluegate.org--2004 \
      /home/octopus/{archives}/octopus@bluegate.org--2004

のようにする。この規則を明示的に破る必要がある場面もある。 詳しくはアーカイブミラーなどの章を参照してほしい。

上記の表での実際の個別のバージョンが含まれるサブディレクト リについてさらに詳しく説明する。サブディレクトリは、 ./C/C--B/C--B--V/R の形をしている。最後の R はリビジョン名でディ レクトリである。このディレクトリ中にはリビジョンのタイプに応じて 各種のファイルが格納される。リビジョンのタイプは、初期リビジョン[i]、 チェンジセットリビジョン[x]、継続リビジョン[c]の三つがある。初期 リビジョンとは import コマンドで新規に作成されたリビジョンで、チェ ンジセットではなく初期ツリー全体が格納されている。通常は継続コマ ンド以外の base-0 リビジョンがこれにあたる。チェンジセットリビジョ ンは通常のコミットで作成されたリビジョンで、直前のリビジョンから の差分情報のみをもつ。patcn-n の形のリビジョンは普通この形になる。 継続リビジョンは tla tag コマンドによって作られた継続情報を持つ ような特殊なリビジョンである。

表 A.3. ファイル一覧

ファイル名i/x/c説明
C--B--V--R.tar.gzicx基本的には初期リビジョンのみで 存在する、初期ツリーの状態そのものを tar で固めたファイ ル。このファイルを展開すれば初期リビジョンがそのまま取得 できる。tla cacherev コマンドでリビジョンをキャッシュし た場合にはチェンジセットリビジョンでも存在する。
C--B--V--R.patches.tar.gz_xcチェンジセットリビジョンでは直前のリビジョンから の差分を示すチェンジセット(これはディレクトリであること を思い出してほしい)を tar で固めたファイル。継続リビジョ ンの場合にも継続を示すチェンジセットが格納されるが、これ はほとんど空で、継続を意味するパッチログのみを含む特殊な チェンジセットになる。
CONTINUATION__c継続リビジョンでだけ存在する。 継続元のリビジョンが A/C--B--V--R の形式で保存されたファ イル。
checksum???このリビジョンの本来の内容を示 す *.tar.gz ファイルに対して計算 されたチェックサムの値が入ったファイル。サインつきアーカ イブの場合にはさらにこの結果にサインが施されている。
checksum.cacherev???このリビジョンが tla cacherev によってリビジョンキャッシュを含む場合、そのキャッシュ用 の *.tar.gz ファイルに対して計算されたチェックサムの値が 入ったファイル。サインつきアーカイブの場合にはさらにこの 結果にサインが施されている。
log???このリビジョンのパッチログ。こ のファイルは *.tar.gz ファイル中にまったく同一のものが存 在するが、簡単に参照できるようにするため単独ファイルの形 で重複して存在している。これを見れば *.tar.gz を展開して その中のファイルをわざわざ取り出さなくてもこのリビジョン でどのような修正があったかを大まかに知ることができる。
++revision-lock???バージョン中の最新リビジョンディ レクトリに存在する。リビジョンがこのバージョンに追加され る際に排他制御を正しく行なうために存在するディレクトリ。 トランザクション実行中以外は、このディレクトリには +contents という名前の、ファイルを一つも含まない唯一のサ ブディレクトリが存在する。リビジョン追加のトランザクショ ンについては XXX を参照してほしい。

ライブラリ領域

ライブラリ領域は、実際に tla get されたリビジョンのプロジェ クトツリーがそのまま集められた巨大な領域である。同じバージョン中 のリビジョン同士では変更が加えられていないファイルも多いので、そ のようなものについてはハードリンクの手法を利用することで空間を節 約している。

表 A.4. ファイル一覧

ファイル名F/D説明
=sparseFライブラリを sparse 属性にする かどうかを決めるフラグとしてのファイル。ファイル内容は空 である。このファイルが存在すると、ライブラリは sparse とさ れる。sparse とは、あるリビジョンをライブラリに追加する ときに副産物として計算することのできる別のリビジョンを同 時に自動的に追加するかどうかを決めるもので、sparse を指 定するとこの自動追加機能が働かない。結果としてライブラリ 領域のサイズは小さくなる。
=greedyFライブラリを greedy 属性にするかどうかを決めるフ ラグとしてのファイル。ファイル内容は空である。このファイ ルが存在すると、ライブラリは暗黙に計算されるリビジョンを ライブラリに登録する。たとえば tla get コマンドであるリ ビジョンのプロジェクトツリーをどこかに構築した場合、この プロジェクトツリーを特に指定しなくてもライブラリに追加す る。これはライブラリコマンドを実行しなくても自然とtlaシ ステムが高速化されることにつながる。
その他のファイルDアーカイブ名をもつディレクトリに なる。このディレクトリ名を A とすると、 ./A/C/C--B/C--B--V/C--B--V--R というディレクトリができて、 最下位のディレクトリ中に、リビジョン A/C--B--V--R のプロ ジェクトツリーの内容が実際に展開される。

./A/C/C--B/C--B--V/C--B--V--R 配下のプロジェクトツリーには 通常展開されるプロジェクトツリーの内容に加えて以下のファイル/ディ レクトリが存在する。

表 A.5. ファイル一覧

ファイル名F/D説明
,,indexFプロジェクトツリー中のファイルと ファイルに対応したインベントリid とのペアのリスト。
,,index-by-nameF,,index と本質的に同じ内容だが、ファイル名でソー トされている。
,,patch-setDこのリビジョン名をもつチェンジセッ トが保存されているディレクトリ。通常のチェンジセットのほ かに、=ancestor, =previous, =log.txt の三つの追加情報も 保存されていて、パッチログメッセージやこのリビジョンの前 のリビジョンなどの関係を把握することができるようになって いる。

.arch-params

各種一時ファイル

ここでは GNU arch 内部で利用されるさまざまなファイルをでき る限り網羅して説明する。これらのファイルは内部的に利用されるだけ で通常利用者が直接考慮する必要はないものだが、ハックの際には必要 だろう。列挙したファイルがすべてではないし、GNU arch の細かいバー ジョンによって増減や名称変更があると思う。この点についてはご了承 願いたい。