regexps.com
二つのプロジェクトツリー(ふつうは同じプロジェクトの)を比較し、 それらの間で変化したものを正確に考えることは, しばしば非常に有用です。 そのような変更の記録は チェンジセット (changeset) あるいは デルタ (delta) と呼ばれます。
チェンジセットは arch
の最も中心的な概念です。
arch
の多くはチェンジセットと共に実行される操作で定義されます。
"古いツリー"と"新しいツリー"の間の チェンジセットを持っていれば、 古いツリーに"このチェンジセットを適用して", 新しいツリーを得ることができます. 言い換えると、チェンジセットにより記述された変更を自動的に加えることができます. 三番目のツリーを持っていれば、パッチを適用して三番目のツリーに 同じ変更をすることが近似的にできます.
arch
は、チェンジセットを作成し適用するための精巧なツールを含みます.
mkpatch
は、2つのツリーのあいだの違いを記述するチェンジセットを計算します。
基本的なコマンドの文法は次のとおりです:
% tla mkpatch ORIGINAL MODIFIED DESTINATION
これは ORIGINAL
ツリーと MODIFIED
ツリーを比較します.
mkpatch
は新しいディレクトリである, DESTINATION
を作成し、チェンジセットをそこに格納します。
mkpatch
がツリーを比較する場合、インベントリ id を使います。
例えば、二つのディレクトリ, あるいは, 二つのファイルは,
それらが同じ idを持っている場合、"同じディレクトリ(あるいはファイル)"
とみなします. これは, それぞれが各々のツリーのどこにあるかは関係しません.
(ソースのインベントリ Id を参照.)
mkpatch
によって生成されたチェンジセットが記述することは、
どのファイルおよびディレクトリが追加されたり削除されたか,
どれが改名され、どのファイルが変更されたか(そしてどのように変更されたか)、
またどのファイルのパーミッションが変化したか(かつどのように)です.
通常のテキストファイルを比較する場合、
mkpatch
は差異を記述するコンテキスト diff を生成します。
mkpatch
はバイナリファイルを比較することも
(新旧バージョンが異なる場合、それらの完全なコピーを保存します),
シンボリックリンクを比較することもできます (新旧リンクターゲットが異なる場合、
それらを保存します).
チェンジセットのフォーマットの詳細な記述は付録にて提供されます (arch のチェンジセットフォーマットを参照).
dopatch
はチェンジセットをツリーに適用するのに使います:
% tla dopatch PATCH-SET TREE
もし, tree
が mkpatch
の調べた "修正前"のツリーと正確に同じものであるなら,
その効果は tree
を変更させて mkpatch
の調べた
"修正後"ツリーと正確に同じにするでしょう. ただし, 一点の例外を
除きます (説明は以下).
"正確に同じ"が意味することは、ディレクトリ構造が同じであり, シンボリックリンクターゲットが同じ、通常のファイルの内容が同じで、 ファイルパーミッションが同じであることです。 変更時刻、複数の(ハード)リンクを持つファイル, およびファイル所有権は、 確実には保存されません。
"正確に同じ"の規則の例外は、
もしパッチが要求することが, ファイルやディレクトリが tree
から取り除かれることである場合,
これらのファイルとディレクトリは tree
のサブディレクトリに保存され,
そのサブディレクトリの名前は, 目の割れるような, 次のパターンに一致します:
++removed-by-dopatch-PATCH--DATE
ここで, PATCH
はパッチセットディレクトリの名前であり、
DATE
はタイムスタンプです。
dopatch
がパッチを当てたツリーが,
mkpatch
によって調べられた修正前のツリーと正確に同じでは
無いとするとどうなるでしょう?
以下は、何を期待するかについての手短な記述です。
dopatch
プロセスの完全な資料はソースコードに含まれてます。
dopatch
は、パッチの対象となるツリーのインベントリを取得します.
インベントリ id を使って, どのファイルとディレクトリがツリーに存在するか
不在であるかがチェンジセットで予定されてるかを決定し, ファイルとディレクトリが
ツリーのどこにあるかを計算します.
単純なパッチ (Simple Patches) チェンジセットが
通常のパッチや, リンク, ディレクトリあるいはファイルのメタデータを持っていて,
そのファイルがツリーに存在するなら, dopatch
はそのパッチを
普通の方法で適用します.
もしパッチをクリーンに適用したら, 変更後のファイル, リンク, ディレクトリは
そこに残ります.
もし単純なパッチがクリーンに適用できないとき,
dopatch
は常に .orig
ファイル
(ツリー下のパッチ対象の適用前のファイルで, 変更無しのもの)と, .rej
ファイル (適用できなかったパッチの一部分)を残します.
もしパッチがコンテキスト diff ならば、
dopatch
はさらにファイル自体を残すでしょう
-- 部分的にパッチを当てて.
もし(失敗した)パッチがバイナリー・ファイルに対してのものなら, 部分的にパッチ当てされたファイルは残りません. 代わりに, そこに残るのは:
.orig -- パッチ対象のツリーに元からあるファイル, 変更無し. .rej -- 変更後のツリーからのファイルの完全なコピーで, パーミッションは `.orig'からのコピー. .patch-orig -- `mkpatch'をした修正前のツリーのファイルの 完全なコピーで, パーミッションは修正前のまま もしくは `mkpatch'を使ったときの修正前のツリーの シンボリックリンクで, パーミッションは 修正前のツリーと同じ.
もし(失敗した)パッチがシンボリックリンクに対するものなら、 部分的にパッチの当たったファイルは残りません. 代わりに, そこに残るのは:
.orig -- 修正前のツリーからの無修正ファイル .rej -- パッチ対象のシンボリックリンクで, パーミッションは .orig と同じもの .patch-orig -- `mkpatch'を動作させたときの修正前のツリーからの 完全なコピーで, パーミッションは修正前のに 保たれている もしくは `mkpatch'を動作させたときの修正前のツリーにあった シンボリックリンクで, パーミッションは修正前のツリーと 同じ
存在しないファイルへのパッチ
存在しないファイルとディレクトリへのパッチはすべて、 パッチの当たったツリーのルートのサブディレクトリに格納されます. このディレクトリ名はは次のものです
==missing-file-patches-PATCH-DATE
ここで PATCH
はチェンジセットディレクトリのベースネームであり、
DATE
はタイムスタンプです。
ディレクトリの再配置と新ディレクトリ
ディレクトリは, 期待するとおり, 追加されたり, 削除されたり, 再配置されます. たとえ期待することが何かを知らないでもです.
mkpatch
が呼ばれたときに, ORIGINAL
ツリーが次のものを持ってたとしましょう:
Directory or file: Id: a/x.c id_1 a/bar.c id_2
しかし、MODIFIED
ツリーは次のようになっています:
a/x.c id_1 a/y.c id_2
両方のファイルに変更があります.
パッチは id が id_2
であるファイルの名前を y.c
にして,
id が id_1
と id_2
のファイルの内容を変えることを
要求するでしょう.
例えば、次のようなツリーを持っているとします:
a/foo.c tag_1 a/zip.c tag_2
そして、そのツリーにパッチを適用します。パッチ後は、次が残ります:
a/foo.c tag_1 a/y.c (was zip.c) tag_2
両方のファイルの内容にパッチが当たります.
次は, 微妙な点と衝突の取扱の例です:
mkpatch が使われたときの修正前のツリーが次のような具合だとします:
Directory or file: Id: ./a id_a ./a/b id_b ./a/b/c id_c
そして、修正後のディレクトリの様子は:
./a id_a ./a/c id_c ./a/c/b id_b
最後に, 問題のツリーの様子は以下だとします:
./x id_a ./x/b id_b ./x/c id_new_directory ./x/c/b id_different_file_named_b ./x/c/q id_c
パッチをそのツリーで当て終えたとき、次のようになります:
./x id_a これは, パッチは id_a のディレクトリは 何も変化させないため. ./x/c.orig id_new_directory ./x/c.rej id_c パッチは id_c のディレクトリを名前が "c" で id_a のサブデイレクトリとすることを要求します. しかし, このツリーはすでに id が id_new_directoryである 別のディレクトリを持っているためです. ./x/c.rej/b id_b パッチは id_b のディレクトリ名を変えて "b" となる, id_c のディレクトリのサブディレクトリにすることを要求する ためです. ./x/c.orig/b id_different_file_named_b パッチはこのファイルに新しい変更を施し, その親ディレクトリの下に居つづけさせるためです.arch Meets hello-world: A Tutorial Introduction to The arch Revision Control System
regexps.com