🌈

git diff --color-moved を使って、行を移動したときに内容が変わっていないことを確認する

に公開

リファクタリングなどでメソッドやまとまった処理をファイル内で移動したコミットを作成した際、移動前後でその内容が変わっていないことを確認します。
特にレビューでコミットを確認する際に使えるかと思います。

git diff は特にオプションをつけないと単に移動元は削除 (赤) 、移動先は追加 (緑) で表示されます。
しかし位置が変わっただけでコードの内容が変わっていない場合、本質的に差分があるとはいえません。
加えて、移動前後でコピペミスなどで差分が生まれてしまった場合でも、移動の分の差分にのまれてしまい diff 上で気づくことが難しくなります。

これを解決するためのオプションが、今回紹介する --color-moved オプションです。

コマンド

特に値を指定しないとzebraになる

git diff <コミットまたはコミット範> -- <ファイルパス (省略可)> --color-moved --color-moved-ws=ignore-all-space

--color-moved=dimmed_zebraにすると、移動差分がまとめてグレーになる

git diff <コミットまたはコミット範> -- <ファイルパス (省略可)> --color-moved=dimmed_zebra --color-moved-ws=ignore-all-space

結果の見方

zebraの場合。
※設定により変更可能。以下はデフォルト設定と思われる配色。(自環境検証)

意味 詳細
赤 (通常の削除行) 削除された行 変更前のコードで、変更・削除された部分。
緑 (通常の追加行) 追加された行 変更後のコードで、新しく追加された部分。
ピンク/マジェンタ 移動元のブロック --color-moved が検出した「同じ内容のブロックが別の位置に移動した行」。
シアン (水色) 移動先のコードブロック①
黄色 移動先のコードブロック② 移動された複数のブロックがある場合、色を分けて視覚的に区別。(zebra オプションの効果)
通常色 (白や黒など端末のデフォルト) 変更なし 移動や変更の対象ではない、元のコードそのままの行。

参考

Git - git-diff Documentation > --color-moved[=<mode>]

Gitの「--color-moved」オプションがかなり便利だったの紹介してみる #Git - Qiita

git diffオプション:目的別まとめ – エンジニア術

Discussion