git diff で無視したい行があるとき

比較時に特定の文字列を含む行を無視したい

最近 Cisco 機器の設定を git で管理しているのですが、diff を取ると設定をいじっていなくても ntp clock-period の行が表示されてしまいます。 この値は機器が動いている間に自動調整されるものなので変わっていても問題ありません。


-ntp clock-period 36027555
+ntp clock-period 36027579

何とか無視できないかと調べたところ git-diff には -G オプションというものがあり、正規表現にマッチしたものだけ表示することができるのがわかりました。 しかし、今回は特定の文字列を含む行を除外したいので文字列の否定ルールを表現しなければなりません。 一般的にこのような場合は「否定の先読み」と呼ばれるパターンを使います。 今回のケースだと以下のようになります。


^(?!ntp clock-period)

しかし残念なことに git-diff は先読み表現に対応していないようで、エラーとなってしまいました。 なので、強引にルールを書いてみます。 以下のようにオプションをつけて git diff を実行すると ntp clock-period の行は消えます。


-G "^([^n]|n[^t]|nt[^p]|ntp[^ ]|ntp [^c])"

ちょっと不格好ですが、これで何とかなります。 ntp 関連で c から始まるコマンドは ntp clock-period のみなので、「ntp c」までを除外すれば十分です。

diff を外部ツールとして登録してみる

ところで通常の diff には -I オプションというのがありこちらはマッチしたものを無視するのですんなり書けます。

-I "^ntp clock-period"

なのでこのオプション付きで diff を外部ツールとして登録し git difftool コマンドから呼び出すという手もあります。


[diff]
        tool = diffcisco
[difftool "diffcisco"]
        cmd = \"diff\" -u -I \"^ntp clock-period\" \"$LOCAL\" \"$REMOTE\"

上のように config ファイルに書いて git difftool を実行するのです。 プロンプトがわずらわしいので -y をつけて抑止すると良いです。


$ git difftool -y

ただし、-I オプションは差分となる固まりの全てが正規表現にマッチしている時に出力が抑止されるという動作なので、前後に変更があれば ntp clock-period の行も出力されることになります。 例えば ntp master コマンドが追加された時は ntp clock-period も出力されることになるでしょう。

git gui で動作させる

Windows 環境で GUI 操作をすることの多い私としては git gui でこれらを実行させたいところです。 git-gui のオプション画面に「Additional Diff Parameters」(config パラメータとしては gui.diffopts) というのがあるので、ここに以下のように入れてみます。


"-G" "^([^n]|n[^t]|nt[^p]|ntp[^ ]|ntp [^c])"

クォーテーションの付け方は試行錯誤の結果なのですが、config ファイルには以下の様に「\"」と記録されます。


[gui]
        diffopts = \"-G\" \"^([^n]|n[^t]|nt[^p]|ntp[^ ]|ntp [^c])\"

すると確かに diff では差分無しと処理されているようですが、「コミット予定に入っていない変更」のリストからファイルを消すことはできず、内容を確認しようとしてファイル名をクリックするたびに変更が無い旨のポップアップが表示される動作となり、残念ながら使い勝手は今一つです。

git diff はそんな状況なので変更有無の確認には git difftool を使うのが良いようです。 「ツール」-「追加」で git difftool -y を呼び出せるようにしておきます。 config には以下のように出力されます。


[guitool "git-diff"]
        cmd = git difftool -y

こうしておくことで git gui 上から git difftool を実行して変更を確認することができるようになります。


2012.10.4
正規表現に誤りがあったため、記事を修正しました。