空想犬猫記

※当日記では、犬も猫も空想も扱っておりません。(旧・エト記)

unified diff

patchやSVNで標準的に使われているdiffのフォーマットについて調べてみた。CVSでも cvs diff -u とするとunified diff形式で出力できる。個人的には cvs diff --unified=5 --ignore-all-space --ignore-blank-line がお勧め。--unified=n に与える数字で前後のコンテキストも抽出してくれるため,diff のテキストだけで大まかな変更を把握することができるようだ。
ここにちょうど良いサンプルがあったので引用してみる。ポイントは6つくらいしかない。

 --- E:?temp?Eustace1.txt	Sat Apr 28 00:51:11 2001
 +++ E:?temp?Eustace2.txt	Sat Apr 28 00:51:18 2001
 @@ -3,12 +3,11 @@
  when he suddenly came across a stream.
  
 +Eustace almost fell into the stream, but
 +skidded to a halt just in time.
 +
  Sitting on a rock in the middle of the
 -stream was a small green frog, basking in the
 +stream was a small blue frog, basking in the
  afternoon sunshine.
  
 -"Hello small green frog!", said Eustace. "What
 +"Hello small blue frog!", said Eustace. "What
  are you doing there?"
 -
 -Froggy didn't answer, so Eustace trod on him
 -and wandered off into the nearby forest to look
 -for wild onions.
  1. 「-」は比較元ファイル,「+」は比較対象(変更された)ファイルを示唆する
  2. 「---」「+++」は連続して現れ,比較ファイルのパスとタイムスタンプが書かれる。「ここからこの2つのファイルを比較するよ」の意味
  3. 「@@ -a,b +c,d @@」は,比較元(-で示唆されてる)のa行めからb行めまでのブロックと,比較対象のc行めからd行めまでのブロックの比較であることを示す。
  4. 「-」で始まる行は,比較元にしかない(削除された)行
  5. 「+」で始まる行は,比較対象にしかない(追加された)行
  6. 半角スペースで始まる行は,両方に共通する行

というわけで,非常に覚えやすいですね(同意を強制する「ね」を使ってみた)。
unified diffの面白い所は,前後の数行を抜き出すことができる点。

% cvs diff --unified=0 --ignore-all-space --ignore-blank-line

とすれば,純粋に変更された行だけしか表示されない。逆に,

% cvs diff --unified=100000 --ignore-all-space --ignore-blank-line

などとすれば,実質的に全行をdumpして,変化のあった行だけにマーカを付けてくれる。このdump結果はパースしやすいので,diffの可視化スクリプトの入力に使ったりすると,実装がかなり楽になりそう。