開発ブログ

WWWクリエイターズが送る、Git、CSS、HTML、コマンドライン、Macの便利機能など、開発に関する役立ち情報発信します。気まぐれに更新。

git diff を徹底攻略!よく使う便利オプションのまとめ、完全版。

最終更新:2017-07-25 by Joe

「git diff」はブランチ管理に必須コマンドとなっており、最もよく使うコマンドのひとつです。「ファイル名の比較」をはじめとする、ファイルの比較・管理に始まる、git diff のよく使うオプションを覚書きしました。

これであなたもgit diff マスターに、ぐんと近づけると思います。

git diff の基本動作と、主要なオプション

git diff」の基本動作は「作業ツリーに行われた変更の表示」です。

引数に「比較元」を指定できますが、もし、比較元を指定しない場合は、デフォルトで、インデックスを比較元とし、 [インデックス] → [作業ツリー] と比較した際の差分を表示します。

この動作仕様の認識が曖昧な方も、少なくないのではないでしょうか。

下記、最も主要な git diff の利用ケースを列挙します。

インデックスとの差分を見る

最も基本的な比較です。インデックスとの差分を見ますので、まだ変更していないインデックスに対しては、作業ツリー上で行った変更を簡単にチェックできます。

最新のコミットとの差分を見る

「HEAD」は現在のブランチの先頭のコミットへの参照です。git diff の比較元に、コミットを指定することで、[そのコミット] → [作業ツリー] の差分を表示しますが、HEADと参照を指定すれば、当然、現在あなたがいるのブランチの先頭(すなわち最新コミット)を指定できます。

指定したコミットとの差分を見る

もちろん、HEADで参照されるコミットでなく、特定の比較元となるコミットを指定することで、[比較元] → [作業ツリー] の比較を行います。

インデックスとHEADの差分を見る

冒頭で、git diff の基本は「作業ツリー」に行われた変更を表示する、と言及しましたが、この動作を下記の「--cached」オプションを利用する事で、「インデックス(ステージ領域)」への変更を見るようになます。

こちらも、git commit を行うの直前に「あれ?結局何を [git slug=”git-add”]add[/gitc]したんだっけな〜」と確認するために非常によく使うコマンドです。

デフォルトは、HEADが比較元になります。

Git の作業領域について

上記で紹介した3つの比較です。よく使います。

やりたい事 git diffコマンド
インデックス → 作業ツリー git diff
HEAD → 作業ツリーの比較 git diff HEAD
HEAD → インデックス git diff --cached

「diff」と「diff --cached」の比較対象の違い

通常は作業ツリーへの差分、--cachedでインデックスへの差分を見るように動作します。

git diff の基本動作

HEADは「作業中ブランチの先頭コミット」を指しますので、現在の作業の進捗差分を見たい時はもっぱら「git diff」「git diff --cached」「git diff HEAD」のいずれかを使うことになると思います。

インデックスと、コミットの関係

「インデックス」は「ステージ領域」とも呼ばれますが、この概念が GIT 特有なので、入門者は非常に混乱しやい点だと思います。少しまとめます。

まずはインデックスと作業ツリーの存在、git addgit commitの関係です。インデックスは将来的に(commit されれば)、正式なコミットになります。

上図で、作業ツリーの近くで汗をかいてがんばっているのは、もちろんあなたです。いつもお疲れ様です。

git diff の便利なオプション

使用頻度はそれほどでもないですが、非常に便利な git diff のオプションです。

ファイル名だけを表示する

差分が生じたファイルの、ファイル名の一覧を表示します。

比較するファイルを限定する

「ファイル名」と書きましたが、実際は「パス」(ディレクトリ名など)を指定して、比較する範囲を限定できます。

ついでに、似たような結果を得られるのがこちら:

一般的に Git において、指定する<コミット名>の代わりに、<コミット名>:<ファイル名> とすることで、範囲を限定した参照を指定することができます。これを利用して、git diff においても、比較対象を限定するというケースですね。

一応、こちらは、git object の指定方法に関する参考文献です:git book > docs > gitrevisions (英語)

特定のコミット同士を比較する

さて、git diff では、2種類のコミットを指定することもできます。

この場合、比較元 → 比較先 でなにが変更されたのかが、表示されます。(右から左に時系列がながれます)コミットの指定はコミットのID(SHA-1)、ブランチ名、HEAD(現在のブランチの先頭)など、特定識別子があれば大丈夫です。

直前のコミットの内容を表示

また、例えば、HEAD^など、「^」を使って1個前のブランチを比較するのはよく使います。こんな感じです。

実際は、git show でよく似た効果が得られます。

上記は、HEADがマージコミットでない事に注意して下さいね、git showの動作が異なってしまいます。

git show はまた別の機会に深掘りしましょう。

リモートブランチとローカルブランチの差分を比較

コミット同士の比較の応用編です。リモートブランチからmasterをpull する前に「どのくらい先にすすんじゃったんだろ?」なんて、事前に調べたい時に使います。

git pull は、いうなれば「git fetch & git merge」ですので、いきなり git pull を実行すると、いきなりローカルブランチにマージがかかってしまいます。

これを事前にdiffで差分を確認します。イメージしやすいように、masterブランチの例で書くと・・・、

git fetchgit merge の振る舞いに関して、もやっとしている人は、ぜひこちらの記事を御覧ください:

差分の表示方法における設定

スペースを無視する

スペース(whitespace)だけの違いを、変更とみなさず、無視します。整形した行は表示しないでほしい時、ありますね。

前者の「b」は、行の末尾の空白と、1つ以上のスペースが連続しているとき、数の違いが発生して無視します。一方で、後者の「w」は、あらゆるスペースの有無と、スペースの数の差分を無視します。

w はスペースと言っていますが、改行コードの違い無視することもできます。

よく似ていますが、上記の仕様を覚えておけば、状況によって使い分けられそうですね。

文字レベルで違いを表示する

git diff は、通常は行の差分を表示するのですが、文字レベルで違いを表示してくれます。これは細かい変更がある時便利です。

後者は「--word-diff=color」とモードしていをした時と同じです。文字の色が変わるだけになるので、こちらのほうが差分が見やすいです。

--word-diff=<モード> のオプションについて、利用可能なモードを抜粋しておきます:

word-diff のモード一覧

color
色だけを使って差分をハイライトする。

plain (デフォルト)
単語の差分を、[-removed-]と[+added+]を使って表示する。デリミタが入力に発生してもエスケープしない。出力が曖昧になることがある

porcelain
単語の違いを新しい1行を使って表示する。(通常は行内で差分を表現するが、必ず1行でadd, removedを表現する、porcelainは、結構読みにくいです・・。)

none
--word-diffを.gitconfigなどで強制している際に、word-diffをオフにするときに使う。

git diff --word-diff=plain の例

git diff word-diff=plain

git diff --word-diff=color の例

git diff word-diff=color

変更が多く細かくなると、後者のほうが見やすい、かもしれませんね。

参考リンク

最後に git diff の参考リンクです。だいたい公式マニュアルが最強です。

 

さて、git diff に関しては、以上です。

git diff は、非常によく利用するコマンドなので、正確に理解しておくとハッピーになれると思います。

それでは、楽しい Git ライフを。