WEB+DB PRESS Vol.46WEB+DB PRESS Vol.46で取り上げたGNU diff(1)のラッパー、「di」をGitHubに置いた。GNU diffには多彩なオプションが用意されているが、POSIXなどの規格の縛りもありデフォルト設定が日常利用には不便なものになっている。いちいちdiff -Nrpu dir1 dir2なんて面倒くさい。以下の特長を持つラッパーdiで楽をしよう。

  • -U3 -N -p -dがデフォルト。
  • 出力が色付き。ページャが起動される。(Gitのまね)
  • バックアップファイルやオブジェクトファイル、.git, .hg, .svn, CVSなどのディレクトリを無視する。
  • RCS/CVSキーワードタグの違いを無視する。
  • ディレクトリを与えれば自動で再帰比較。
  • 上記を含むデフォルトのオプション設定は環境変数で変更可能。
  • GNU diffがサポートしないオプションの組み合わせもサポート。

alias di="diff -ru"でいいんじゃないの?」という人は、理不尽におこられた経験がないのかもしれない。context diffがほしくなってdi -c FILE1 FILE2とすると、展開されてこうなる。

% diff -ru -c FILE1 FILE2
diff: conflicting output style options
diff: Try `diff --help' for more information.

黙って後から指定した方を採用してくれればいいのに、まったく余計なお世話だ。(FreeBSDではこのエラーは抑止されている)
そして、diff FILE1 DIRは動くのになぜかdiff FILE1 FILE2 DIRはエラーになるのも不便だ。

% diff FILE1 FILE2 DIR
diff: extra operand `DIR'
diff: Try `diff --help' for more information.

diだとちゃんと動く。ほかにも、-r-D NAMEが組み合わせられない問題も自力でディレクトリを辿ることで回避している。
インストールは、単にbin/diをパスの通ったところに置くか、またはgem install diでOK。動作にはRubyが必要。
弱点は大きなツリーの比較が遅いこと。GNU diffは-x/--excludeを使ってもファイル名でしか除外できず、二つのファイルリストを渡して比較するということもサポートしていないため、自力でディレクトリ探索を行う場合はディレクトリごとにdiff(1)を複数回起動しなければならない。しかし、並列起動で高速化する余地はあるので今後の課題。
もう一つ、--ignore-file-name-caseをサポートしていないが、これは面倒な割には使いたいと思ったことがないため。それだけなので、気が向けば実装するかも。あるいは切実にほしいあなたが実装するかも。

Tags : ,
Categories : Tech