Help us understand the problem. What is going on with this article?

忘れやすい人のための git diff チートシート

More than 1 year has passed since last update.

git diff は色んな場面で本当によく使うんですが、できることが多いだけに全然覚えられずに毎回調べてしまいます。
なので、場面ごとに使えるコマンドを一覧でまとめてみました。

先にワークツリーとインデックス【Gitの基本】- サルでもわかるGit入門を読んでおくと、ここに書いてある diff について理解しやすいと思います。

git pull する前にリモートとの変更点を見る

git diff HEAD..リモート名/ブランチ名

git pull をする前にローカルの最新コミットと pull 先のリモートリポジトリとの変更点が見たいときはこのコマンドで見れます。
ここでいうリモート名は origin とかそういうやつです。

git push する前にリモートとの変更点を見る

上記のコマンドは、こんな感じで逆にもできます。

git diff リモート名/ブランチ名..HEAD

.. の右側が時系列的に最新とみなされるので、この場合は git commit した後にリモートリポジトリとそのこれから push したい箇所を表示したい場合に使えます。

git add する前に変更点を見る

git diff

git add する前に変更した箇所とインデックスとの変更点が見たいときはこのコマンドです。

git add した後に変更点を見る

git diff --cached

git add した後にインデックスと最新のコミットとの変更点を見たいときは --cached を付けます。

--staged も同じ意味なのですが、直感的な命名なのでむしろこっちのほうが覚えやすいかもしれません。

今回コミットした変更点を見る

git diff HEAD^

git commit した後に、コミットした箇所を表示したい場合はこのコマンドで見れます。
「最新のコミット」と「最新のコミットのひとつ前」との差分ということです。

本来は git diff HEAD^..HEAD と書くのが正しいのですが、.. の右側を省略すると暗示的に現在のブランチのHEADを示すことになるので、この書き方で問題ありません。

cherry-pick したときに、どんなファイルが更新されたかを調べたい時もこれで見れます。

コミット同士を比較する

git diff 変更前のSHA..変更後のSHA

SHA さえ分かればそのコミット同士の変更点もこのように確認できます。
SHA は GitHub のコミット一覧で表示されているこういうやつです。

あるコミットの変更点を見る

git diff 確認したいコミットのSHA^..確認したいコミットのSHA

確認したいコミットの SHA だけ分かれば、^ を使うことでそのコミットで変更されたファイルも確認できます。

ブランチ同士を比較する

git diff ブランチA..ブランチB

Pull Request を送る前に、自分が作ったブランチとマスタとの変更点を見たいときなどに使います。

ある1ファイルの変更点を見る

git diff -- 対象のファイルパス

git add する前に、ある変更したファイルに対しての変更点が見たい場合はこう書きます。
パスなので、もちろんディレクトリ単位での比較もできます。
ちなみに git が引数をファイルと推測できる場合は -- は省略可です。

特定のファイルを別のブランチと比較したい場合はこんな感じになります。

git diff ブランチA..ブランチB -- 対象のファイルパス

別ファイル同士を比較する

git diff -- ファイルパスA ファイルパスB

-- の後は常にパスとして認識されます。
で、それを2つ並べるとそのパス同士の比較になります。

どれくらい変更したかだけを見る

git diff --stat

変更点をすべて表示するのではなく、ファイルごとにどれくらい変更したかを表示したい場合にこのオプションを使います。こんな感じです。

変更したファイルが多くて、かつ変更したらマズイファイルが含まれていないかをパッと確認したい時に有用です。

ファイル名だけ見る

git diff --name-only

変更点を表示するときに、変更があったファイルのパスだけを表示してくれます。

これ単体で使うというよりも、cp などの外部コマンドとかと組み合わせて変更ファイルに対して一括処理をすることが多いです。

git add -n .; git diff --name-only

こう書くと、いったん git add の dry-run した上で追加されたファイル名も含めてくれます。
git status と違って出力結果がファイル名だけになるので、いろいろ応用できるコマンドです。

改行コードや空白を無視する

git diff -w

改行コードの違いや、文頭・文末の空白を無視したい場合は -w を付けます。
-b もありますが、-w さえ覚えておけばほとんどのケースで問題無いです。

空行を無視する

git diff --ignore-blank-lines

--ignore-blank-lines オプションを付ければ空行が増減しても無視してくれます。

変更点の前後に表示される行数を変える

git diff -U0

こうすると前後の行数が消えます。逆に -U10 とかにすれば前後10行が表示されます。

単語単位で比較する

git diff --color-words

メソッド名を変更したときなど、行単位ではなく、単語単位で比較したい場合に --color-words オプションを付けると見やすくなります。

gitのdiff, status, logを極限までコンパクト化+便利化する

この記事にあるように .gitattributes と組み合わせると、言語単位での比較をしてくれて、より分かりやすくなるのでオススメです。

Excel の中身を比較する

上記を応用すると Excel の変更点も見れます。

Mac の場合は Homebrew を用意しているので下記コマンドを、

brew tap shibukk/git-xlsx-textconv
brew install git-xlsx-textconv

Windows の場合はこちらのリンクにある git-xlsx-textconv_windows_amd64.zip という zip ファイルをダウンロード・解凍して、パスの通っているフォルダに置いて下さい。

あとは差分が見たいプロジェクト直下にある .git/config.git/info/attributes にそれぞれ下記を記述するだけで OK です。

.git/config
[diff "xlsx"]
  binary = true
  textconv = git-xlsx-textconv
.git/info/attributes
*.xlsx diff=xlsx
*.XLSX diff=xlsx

下記コマンドでセル単位の変更点が見れます。

git diff --color-words -- 対象のExcel

こんな便利なツールを作っていただき、@tokuhirom さん本当にありがとうございます!

圧縮された JavaScript ファイルを展開して比較する

圧縮/難読化されたJavaScriptファイルのgit diffをみやすくする

これをそのまんま参考にします。
僕の場合は圧縮した json も比較する必要があったので、json もこんな感じで対象にしています。

.git/info/attributes
*.min.js diff=minjs
*.json diff=minjs

おまけ

Git 2.9.0 から diff が賢くなり、compactionHeuristic を ON にしておくと上方向に比較差分が出るようになりました。
見やすくていいですね。

git config --global diff.compactionHeuristic true
# diffコマンドのオプションに --compaction-heuristic をつけるだけでもOK
diff --git a/foo.rb b/foo.rb
index 64bb579..a2b5573 100644
--- a/foo.rb
+++ b/foo.rb
@@ -3,6 +3,10 @@ module Foo
   def finalize(values)

     values.each do |v|
+      v.prepare
+    end
+
+    values.each do |v|
       v.finalize
     end
 end

↑これが、↓こうなります。

diff --git a/foo.rb b/foo.rb
index 64bb579..a2b5573 100644
--- a/foo.rb
+++ b/foo.rb
@@ -2,6 +2,10 @@ module Foo

   def finalize(values)

+    values.each do |v|
+      v.prepare
+    end
+
     values.each do |v|
       v.finalize
     end

こういう diff のやり方便利だぜ!というのがありましたら、ぜひ教えてくださいmm

shibukk
東京で AWS と Rails をちょっとだけやっています。あと GCP も。
https://www.flickr.com/photos/158672816@N06/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした