29.

git diff の使い方(作業ツリー/インデックス/コミット間/ブランチ間の差分抽出)

編集
この記事の要点
  • git diff = 作業ツリー vs インデックス(git add 前の差分)
  • git diff --cached = インデックス vs HEAD(git add 済の差分)
  • git diff HEAD = 作業ツリー vs HEAD(コミットされていない全変更)
  • ブランチ間: git diff main..feature、コミット間: git diff abc123 def456
  • パッチ出力: git diff > fix.patch → 別環境で git apply fix.patch
  • 見やすく: --stat / --name-only / --word-diff / --color-words

git diff の 3 つの世界

Git には作業ツリー(Working Tree)、インデックス(Staging Area)、HEAD(最新コミット)の 3 つがあり、git diff はそのどの間の差分を見たいかでオプションが変わります。

コマンド比較対象用途
git diff作業ツリー vs インデックスadd 前の変更を確認
git diff --cached
git diff --staged
インデックス vs HEADadd 済の内容を確認(commit 前最終チェック)
git diff HEAD作業ツリー vs HEADコミット前の全変更
git diff 作業ツリー vs 指定コミット古い版との比較
git diff コミット c1 vs c2過去 2 点の比較
git diff main..featuremain から feature への差分ブランチ間レビュー
git diff main...feature共通祖先から featurePR レビューに近い

基本の使い方

# 1) add 前の変更を見る
git diff

# 2) add 済の変更を見る(コミット直前の確認)
git diff --cached
git diff --staged          # 別名

# 3) コミットされていない全変更
git diff HEAD

# 4) 特定ファイルだけ
git diff src/Login.php
git diff -- src/           # ディレクトリ指定

# 5) コミット間の差分
git diff HEAD~3 HEAD       # 3 つ前から今まで
git diff abc1234 def5678

# 6) ブランチ間
git diff main..feature
git diff origin/main..HEAD   # ローカルに溜まっている push 前差分

見やすくする出力オプション

# 変更ファイル名のみ
git diff --name-only HEAD~3
# src/Login.php
# src/User.php

# 変更状態(A=追加、M=変更、D=削除)
git diff --name-status HEAD~3
# M       src/Login.php
# A       src/User.php

# サマリ(追加/削除行数)
git diff --stat HEAD~3
# src/Login.php | 12 +++++++-----
# src/User.php  | 80 +++++++++++++++++++++++++++++++++++++++++
# 2 files changed, 84 insertions(+), 8 deletions(-)

# 詳細サマリ
git diff --shortstat HEAD~3
# 2 files changed, 84 insertions(+), 8 deletions(-)

# 単語単位の diff(リファクタの可読性向上)
git diff --word-diff
git diff --color-words      # カラフル表示

# 関数単位で「どの関数の中か」を表示
git diff --function-context

パッチ生成と適用

環境間でファイル変更を渡したいときの定番:

# 作業ツリーの変更をパッチに保存
git diff > fix.patch

# add 済も含めて全部
git diff HEAD > fix-all.patch

# 特定コミット間のパッチ
git diff HEAD~5 HEAD > last5.patch

# 別環境で適用
git apply fix.patch
git apply --check fix.patch    # 適用可能かだけ確認

# コミット履歴付きで送りたい場合は format-patch
git format-patch -3            # 直近 3 コミットを 0001-*.patch 等で出力
git am 0001-fix.patch          # コミットごと取り込む

外部 diff ツールを使う

# VS Code を difftool に設定
git config --global diff.tool vscode
git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE'

# 使う
git difftool HEAD~1
git difftool --tool=vscode HEAD~1

# Beyond Compare / Meld / WinMerge 等も設定可
git config --global diff.tool meld
git config --global difftool.prompt false   # 毎回確認ダイアログを出さない

よくある使い方レシピ

# 「自分が main から派生してから何を変えたか」(PR レビュー視点)
git diff main...HEAD

# 「上司の変更だけ」を見る
git diff --author=tanaka HEAD~20..HEAD     # ← log 用、diff には未対応
# 代わりに
git log --author=tanaka -p HEAD~20..HEAD

# 「行ベース」じゃなく「移動も追跡」
git diff -M                 # rename を検出
git diff -C                 # copy も検出

# 空白の違いを無視
git diff -w
git diff --ignore-all-space
git diff --ignore-blank-lines

# 特定行だけの diff
git diff HEAD~1 -- "src/*.php"
git diff HEAD~1 -- ":(exclude)vendor/"     # 除外

diff フォーマットの読み方

diff --git a/src/Login.php b/src/Login.php
index e3a4b8c..f5d2c1e 100644
--- a/src/Login.php       ← 旧 (a)
+++ b/src/Login.php       ← 新 (b)
@@ -10,7 +10,9 @@ class LoginController        ← ハンク見出し: 旧10行目から7行/新10行目から9行
     public function login(Request $req)
     {
-        $user = User::find($req->id);     ← 削除行(赤)
+        $user = User::findOrFail($req->id);  ← 追加行(緑)
+        Log::info('login', ['user' => $user]);
         return $user;
     }

FAQ

Q: diff の出力を画面に出さずファイルに保存したい
A: git --no-pager diff > out.txt または git diff | cat > out.txt

Q: 改行コード(CRLF/LF)だけの diff を消したい
A: git diff -wgit config core.autocrlf input でリポジトリ全体を LF に統一。

Q: バイナリファイルの diff が Binary files differ しか出ない
A: 画像なら git diff --binary で base64 化、Office なら .gitattributes で textconv フィルタ設定。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. ls ファイル/ディレクトリ一覧表示
  2. sudo ユーザー指定
  3. cron/crontab ジョブの自動実行と登録方法
  4. wget http通信によるファイルダウンロード
  5. rm ファイル/ディレクトリ削除
  6. pwd カレントディレクトリの表示
  7. cd ディレクトリの移動
  8. ./configure
  9. make
  10. make install
  11. unzip ファイルの解凍
  12. mv ファイル/ディレクトリの移動および名称変更
  13. mkdir ディレクトリの作成
  14. touch 空ファイルの新規作成
  15. vi テキストディタの使用
  16. find ファイル/ディレクトリ検索
  17. grep 文字列の検索
  18. tail ファイルの末尾表示
  19. curl HTTP通信によるリクエスト
  20. nslookup ドメインのIP解決
  21. apt update パッケージリストの情報を更新
  22. apt upgrade パッケージの更新
  23. ln リンク/ショートカットの作成と削除
  24. rsync ファイル/ディレクトリの同期
  25. ssh リモートとの暗号化通信
  26. scp sshを利用したファイルのコピー
  27. unzip zip ファイルを解凍する
  28. cp ファイル/ディレクトリのコピー
  29. diffファイルの差分抽出
  30. fdisk ハードディスクに対する操作
  31. lsblk デバイスをツリー状で表示する
  32. kill プロセスを終了させる
  33. zip ファイルやディレクトリをzip形式に圧縮する
  34. host ドメインからIPアドレスを確認
  35. chmod 権限の変更
  36. ip IPアドレスの確認
  37. chown ファイル/ディレクトリ所有者の変更
  38. chgrp ファイル/ディレクトリのグループ情報の変更
  39. nohupと'&' プログラムのバックグラウンド実行(ssh接続時)
  40. lsof 開いているポート番号の確認
  41. tar ファイルの圧縮と解凍
  42. file ファイルの種類を表示
  43. cat ファイルの中身を表示
  44. head ファイルの先頭部分を表示
  45. wc 行数/単語数/文字数を確認
  46. shutdown システムのシャットダウンと再起動
  47. ps プロセスの確認
  48. which コマンドの絶対パスを調べる
  49. yum RedHat系ディストリビューションの管理
  50. mount ファイルシステムのマウント
  51. 特定フォルダ以下の特定拡張子のファイルを再帰的に削除する方法
  52. 特定のフォルダとそのサブフォルダ内にある特定のファイル名のファイルを再帰的に削除