Mercurial の diff を美しく表示するために必要なたった 1つの設定
このエントリは Mercurial Advent Calendar 2013 の17日目です。
タイトルは Git の diff を美しく表示するために必要なたった 1 つの設定 #git のパクリです。すみません。
↑の記事を読んで、単語単位で diff 表示のできる git + diff-highlight が羨ましくなったのでいろいろ試してみました。
きっかけはこのツイート。
color 拡張で hg diff に色がつくようになって、trailling space を見つけやすくなるんだけど、同じように全角スペースがあるときにも強調表示してくれないかしらねえ。 #mercurialjp
— Takeshi KOMIYA (@tk0miya) 2013, 12月 14
@flyingfoozy 改めて何が欲しいのかを整理してみると、「全角スペース」ではなく文字単位での差分が見られることのような気がしてきました。git-highlight が僕のニーズを(gitで)実現したもののような気がします。 / http://t.co/KMMIHDVYOF
— Takeshi KOMIYA (@tk0miya) 2013, 12月 15
@flyingfoozy と話す中で
- mercurial の diff は行単位で処理しているので、書き換えるのは大変そう (効率も気になる)
- hg diff --color always | diff-highlight とすれば文字単位の diff 表示できるよ
- --colors always しないとカラーリングされないので注意
- でも alias 化する方法はなさそう
- extdiff を使ってコマンドを追加することは可能
ということが分かりました。(というかほぼ教えてもらいました。ありがとうございます)
文字単位の diff 表示をする extdiff を用意してみよう
extdiff で用意する diff コマンドはファイルを 2つ引数に受け取ります。
既に世の中には文字単位の diff 表示をする素敵コマンド diffc が提供されているので
これ使うことにします*1。
$ curl -O http://diffc.googlecode.com/svn/trunk/bin/python2/diffc $ chmod +x diffc
あとは hgrc でこの extdiff を定義するだけです。
[extensions] extdiff = [extdiff] diffc = diffc
訂正 12/18: extdiff の設定方法を cmd.diffc = ... から difc = ... に変更 (@flyingofoozy さん、感謝!)
この設定で hg diffc を実行すると diff が文字単位表示になります。
個人的には unified diff 形式が好みなので、unified diff で比較できるよう手を加えます。
diffc でも -u オプションを指定すると unified diff になるのですが、
extdiff ではコマンドライン引数を設定することができません。
そのため、コマンドライン引数を与えるラッパースクリプトを用意します。
手元では hg-diff-highlight という名前にしています。
#!/bin/sh diffc -u $1 $2
そして extdiff 設定も書き換えます。
hgrc を書き換え、diffc の設定に -u を付け加えます。
[extdiff] diffc = diffc -u
訂正 12/18: extdiff を正しく設定するとラッパースクリプトは不要であるため、記述を変更しました。
そして hg diffc を呼ぶとちゃんと unified diff になります。
さらに extdiff のコマンド名を cmd.diff などに変えると普段使っている hg diff の置き換えとして使うこともできます。
別解: diff-highlight をそのまま利用する
…とここまでまとめていたら、@flyingfoozyからこんな意見を貰いました。
@tk0miya 現状では、pager 経由で常時 "diff-hilight.pl | less -Fr" を使用する、みたいに割り切るのが良いでしょうね。diff以外にも log -p、tip -p、export、record 使用時等でも差分表示がありますし……
— FUJIWARA Katsunori (@flyingfoozy) 2013, 12月 16
ちょっと強引ですが、diff-highlight は「diff っぽい」出力にしか反応しないため、
常時 diff-highlight を呼び出す方がシンプルかもしれませんね。
それに log -p や tip -p などの出力にも応用が効くのはよいことです。
pager に指定する場合は次のように設定します。
[extensions] pager = [pager] pager = diff-highlight | LESS='FRX' less quiet = True attend = annotate, cat, diff, export, glog, log, qdiff
出力はこうなります。
まとめ
extdiff と diffc、そしてちょっとしたラッパースクリプトを組み合わせると
Mercurial でも文字単位での diff ができることをご紹介しました。
また、pager プラグイン経由で diff-highlight を使う方法もあります。
ちょっと便利に hg diff したいときに参考にしてみてください。
追記 12/18: 続・Mercurial の diff を美しく表示するために必要なたった 1つの設定 という記事を書きました。
*1:内部で diff コマンドを呼び出しているようなので、windows 環境では使えないかもしれません。