ITエンジニアによるITエンジニアのためのブログ

git diffオプション:目的別まとめ

git diff は日々のコーディングやコードレビューで最もよく使うコマンドの1つですが、目的によって使うフォーマットやオプションが異なるため、自分がどういう場面でどのようなフォーマットを使っているかをまとめてみました。

  1. SQL View 定義の更新
  2. 別メソッドやファイルへのコード分割
  3. 似通ったスクリプトのコピペ

1. SQL View定義の更新

課題

私は、SQL View定義を更新するたびに新しい定義ファイルを作成しています。例えば、バージョン1ならdb/views/view_v01.sql、バージョン2ならdb/views/view_v02.sqlとなります。

Ruby on Rails では、新しいバージョンにDBスキーマを更新すると自動的にDBスキーマ定義ファイル(db/schema.rb)も更新されます。しかし、コードレビューの際にオプションなしの git diff でこのファイルを確認すると、旧バージョンのViewの行は全てマイナス(-)で、新バージョンのViewの行は全てプラス(+)で表示されてしまい、何が更新されたのかを把握するのが困難になります。

解決策

この問題は、git diffに–color-movedオプションを付けることで解決できます。

git diff --color-moved

こうすることで、内容に変更がなくて場所を移動しただけの行は、追加・削除された行とは別の色で表示されますので、ひと目見ただけで差分を確認できるようになります。

補足

なお、git diffではなく通常のdiffを使い、スキーマ定義ファイルではなく新旧のViewバージョンファイルを比較する方法もあります。

diff -up db/views/view_v01.sql db/views/view_v02.sql

しかし、git diff –color-movedでこの問題を解決できることがわかってからは、その方が他の差分も含めて一発で確認できるため、通常のdiffを使った上記の方法はほとんど使わなくなりました。

2. 別メソッドやファイルへのコード分割

課題

リファクタリングによって冗長なメソッドの一部分を別メソッドに切り出す場合、通常のgit diffでは、コードを別メソッドに移動させると、移動前のコードブロックを古いコンテンツ、移動先のコードを新しいコンテンツとして認識してしまい、本当に削除した箇所や追加した箇所と区別がつかなくなってしまいます。

解決策

このような場合、–color-movedと–color-moved-ws=ignore-all-spaceオプションの組み合わせで解決できます。

git diff --color-moved --color-moved-ws=ignore-all-space

このオプションを使用すると、移動したコードブロックのみならず、移動してインデントも変わったコードブロックも、追加行や削除行とは違う色で表示してくれるので本当に便利です。

例えば、ループの中のコードを別メソッドに切り出す場合、高い確率でインデントも変わってしまうので、このオプションを重宝しています。

補足

・このオプションの組み合わせは、git diffだけでなくgit showでも使えます。

・良く似たオプションに-wまたは–ignore-all-spaceがあります。このオプションもインデントを無視してくれるので、スペースが変わっただけの場合は有効です。ただし、本当に無視されるので、差分自体が表示されなくなってしまいます。また、–color-movedオプションと一緒に使うと、コード移動とインデント変更の両方が行われた場合、インデント変更されたとみなされて差分が全く表示されなくなるので、おすすめしません。

3. 似通ったスクリプトのコピペ

課題

個別クライアント向けに似通ったスクリプトをほぼコピペで作成する場合、設定値など意図した箇所のみが変更されていることを確認する必要があります。

解決策

以下の形式でコピー元のファイルとコピー先のファイルを比較することで、2つのファイルの差分が設定値など意図した箇所のみになっており、間違えてコードの他の箇所を変更していないかを確認できます。

git diff file1 file2

正直、同じワーキングツリー上にある2つのファイルの差分を比較するだけなら、git diffではなく通常のdiffで十分です。ただし、もし片方のファイルが現在のブランチではなく他のブランチにしかない場合は、git diffでブランチ名をファイル名の前に付けることでチェックアウトする必要を省けるので便利です。

git diff branch1:file1 branch2:file2

まとめ

git diff は、オプションを適切に使い分けることで、様々な場面で効果的に活用することができます。本稿で紹介したオプションを参考に、ぜひ git diff を使いこなしてみてください。