diffコマンドをカラー表示にして見やすくする方法

colordiffを使う方法

colordiffというものをインストールすればdiffと同じ使い方でカラー表示できるようになります。

$ sudo apt install colordiff

などで簡単にインストールできます。

$ colordiff -u a.txt b.txt

lessで見る場合は-Rオプションが必要です。このオプションを付けないとカラー表示のためのエスケープシーケンスがそのまま表示されてしまいます。

$ colordiff -u a.txt b.txt | less -R

-uオプションはdiffで私がよく(必ず)使うオプションで、差分の表示フォーマットの指定です。デフォルトのフォーマットよりも個人的には見やすいので使っていますが、git diffの表示フォーマットと同じというメリットもあります。

git diffを使う方法

たいていの開発環境にはgitがすでに入っています。設定が適切ならばgit diffで差分をカラー表示してくれます。git diffはバージョン間やindexとの差分を表示するために使うことが多いですが、バージョン管理とは関係なく2つのファイルの差分を表示することもできます。git diffcolordiffと違って、端末出力の場合に自動でlessを挟んでくれるメリットもあります。

git diffをカラー表示にするには

$ git config --global color.ui true

としておくか、~/.gitconfig

[color]
        ui = true

と書いておきます。

2つのファイルの差分を見るには--no-indexというオプションを使います。バージョン管理とは関係なく2ファイルの差分を見ます。

$ git diff --no-index a.txt b.txt

ディレクトリを指定した場合は、そこに含まれるファイルを再帰的に見てくれます。

git diffの残念な点

git diffで残念なのはファイルとしてパイプを指定できないことです。

たとえばこんな感じです。

$ foo | diff - <(bar)

または

$ diff <(foo) <(bar)

<(...)の部分はBashのProcess Substitutionという機能です。fooコマンドの出力とbarコマンドの出力の差分が表示されますが、これはgit diffではできません。確認はしていませんが動作からしgit diffはパイプや名前付きパイプをうまく扱えないように見えます。

コマンド出力はいったんテンポラリなファイルに書き出してから比較する必要があります。

difflコマンド

git diffがパイプで使えないのが惜しいので、私は以下のような内容のdifflという名前のBashスクリプトをPATHの通った場所に置いて使っています。実際には他にも機能を書き足したもっと長いスクリプトですが、この記事に関連するところとしては以下の内容です。

f1=$1
f2=$2

tmp1=
tmp2=
if [ -p "$f1" ]; then
    # 1つ目のファイルがパイプだった場合はテンポラリに書き出す
    tmp1=$(mktemp)
    cat < "$f1" > $tmp1
    f1=$tmp1
fi
if [ -p "$f2" ]; then
    # 2つ目のファイルがパイプだった場合はテンポラリに書き出す
    tmp2=$(mktemp)
    cat < "$f2" > $tmp2
    f2=$tmp2
fi

git diff --no-index "$f1" "$f2"

if [ -n "$tmp1" ]; then
    rm $tmp1
fi
if [ -n "$tmp2" ]; then
    rm $tmp2
fi

difflという名前は個人的に使っているだけなのでどうでもいいかもしれませんが、diff+lessの省略です。

以上。