パッチログの限界

あるプロジェクトツリーを考える。プロジェクトツリーはいままで 自分自身に適用されてきたチェンジセットのログであるパッチログを記録 している。これらのパッチログの由来について、すこし詳しく考えてみよ う。

パッチログは大きくいって二つのことに由来する。ひとつはこのプ ロジェクトツリーをどこかのバージョンに — 通常はデフォルトバー ジョンに対してということになるが — コミットしたような場合で ある。この場合、そのコミットが作り出した新しいリビジョン名に対応し たパッチログがプロジェクトツリーに追加される。一方アーカイブの対応 バージョンには、一つ前のリビジョンと今回作り出されたリビジョンとの 間の差分であるチェンジセットが新しいリビジョン名で作られるが、この 中にもいま問題にしているパッチログが追加される。tla get でこの最新 リビジョンを get すると、いま作り出されたばかりのパッチログも一緒 にプロジェクトツリーに含まれることになる。

パッチログのもう一つの由来は、今回プロジェクトツリーがコミッ トしようとしているバージョン以外のバージョンからのチェンジセットを このプロジェクトバージョン中にマージすることに由来している。たとえ ば今、A/C--B--V--R にいて、これとは別のバージョン中のリビジョンで ある A1/C1--B1--V1--R1 をマージしたとする。これは直接 replay コマ ンドで選択的に取り込んだのかも知れないし、それを含むようなもっと総 括的なマージの一貫として取り込まれたのかも知れない。いずれにせよプ ロジェクトツリーには A1/C1--B1--V1--R1 のパッチログが追加される。 そしてこのパッチログは、A/C--B--V--(R+1) のコミットで作られるチェ ンジセットに記録され、チェンジセットはアーカイブバージョンに追加さ れるので、アーカイブ領域にも記録されることになる。

ここからは議論を簡単にするため、コミットするバージョンに関係 したA/C--B--V--R のようなリビジョン名を P と表すことにし、コミット バージョン以外のバージョンからのチェリーピックを p, q, r, ... と表 すことにする。P に含まれているのは、プロジェクトツリーに対するマー ジコマンドの適用による、p, q, r, ... のパッチログと、自分自身のパッ チログだ。一方 チェンジセットとしての P の実際の内容は、p, q, r,.. の実際の内容と、P 自身の修正内容になる。マージコマンドだけを実行し たのであればこれは空だが、エディタなどで直接プロジェクトツリーのファ イルを修正した場合には空ではない。だから P = P + p + q + r ... となる(XXX: ひどい説明だ!)。

ものごとには順序に関係したことと関係しないことがあることの例

ここでの問題は、P に適用された P, p, q, r,... の順序が不明だ ということ、また P はアトミックではないということだ。たとえば foo.txt の先頭の方にある行を追加し、p, q, r を適用し、その後 この三つのチェンジセットで追加された行の一部を削除したような場合を 考えると、P という内容がはっきりしなくなってしまう。

問題は他にもある。たとえば p を適用した後、その適用を完全に 取り消すような修正をプロジェクトツリーに手で加えてからコミットすれ ば、パッチログには p が適用されたという情報が残るにもかかわらず、 実質的に p は適用されていない。

まだある。p, q, r の適用順序をパッチログは示していない。p, q, r の順序で適用されたのかも知れないし、q, r, p だったのかも知れ ない。チェンジセットの代数は一般的にはアーベル的ではないので、両者 の結果は異なったものになることもあるのだ。

結論として、パッチログはパッチ適用の履歴についての完全な記述 ではないということになる。これはせいぜいあるチェンジセットがすでに 適用されているかどうかの目安にすぎない。だから場合によってはパッチ ログを操作して、まだ適用されていないチェンジセットがあたかも適用さ れていたり、実際にはすでに適用されたかチェンジセットがあたかもまだ 適用されていないかのようにプロジェクトツリーを「だます」必要がある。 こんな事態は頻繁におこるわけではないが、時には必要になる。GNU arch はもちろんこんな場合にそなえていくつかのコマンドを用意している。 tla add-log-version, tla remove-log-version, がそれである。

パッチログエントリを追加・削除するコマンドは存在し ないのか? またこれは現実の場面では不要なのか?