git diffは、ファイルの変更内容を表示するコマンドです。作業ディレクトリ、ステージングエリア、コミット間の差分を確認できます。コミット前の確認やコードレビューに必須のコマンドです。
基本的な使い方
作業ディレクトリの変更を確認
bash
# 未ステージングの変更を表示
git diff
出力例:
diff
diff --git a/src/app.js b/src/app.js
index a1b2c3d..e4f5g6h 100644
--- a/src/app.js
+++ b/src/app.js
@@ -10,7 +10,7 @@ function login(user) {
if (!user) {
return null;
}
- return user.name;
+ return user.username;
}
ステージングされた変更を確認
bash
# ステージング済みの変更を表示
git diff --cached
# または
git diff --staged
次のコミットに含まれる内容を確認できます。
すべての変更を確認
bash
# 未ステージング + ステージング済み
git diff HEAD
特定のファイルの変更を確認
bash
# 特定のファイルのみ
git diff src/app.js
# 複数のファイル
git diff src/app.js src/utils.js
# ディレクトリ
git diff src/
コミット間の差分
直前のコミットとの差分
bash
# 1つ前のコミットとの差分
git diff HEAD~1
# 2つ前のコミットとの差分
git diff HEAD~2
2つのコミット間の差分
bash
# コミットAとコミットBの差分
git diff commit-a commit-b
# ハッシュを指定
git diff a1b2c3d e4f5g6h
# 範囲を指定
git diff HEAD~3..HEAD
ブランチ間の差分
bash
# mainブランチと現在のブランチの差分
git diff main
# 2つのブランチ間の差分
git diff main feature
# mainにあってfeatureにない変更
git diff main..feature
# 共通の祖先からの差分
git diff main...feature
よく使うオプション
--cached, --staged: ステージング済みの変更
bash
git diff --cached
git addでステージングした内容を確認します。コミット前の最終確認に使います。
--name-only: ファイル名のみ表示
bash
git diff --name-only
出力例:
plain
src/app.js
src/utils.js
tests/app.test.js
--name-status: ファイル名と状態
bash
git diff --name-status
出力例:
plain
M src/app.js
A src/new-file.js
D src/old-file.js
M: Modified(変更)A: Added(追加)D: Deleted(削除)R: Renamed(リネーム)
--stat: 統計情報を表示
bash
git diff --stat
出力例:
plain
src/app.js | 15 +++++++++------
src/utils.js | 8 ++++++++
tests/app.test.js | 23 +++++++++++++++++++++++
3 files changed, 40 insertions(+), 6 deletions(-)
--color-words: 単語単位で色分け
bash
git diff --color-words
行全体ではなく、変更された単語だけを強調表示します。
-w, --ignore-all-space: 空白の変更を無視
bash
git diff -w
インデントやスペースの変更を無視して、実質的な変更のみ表示します。
--word-diff: 単語単位の差分
bash
git diff --word-diff
出力例:
diff
return [-user.name-]{+user.username+};
-U, --unified: コンテキスト行数を指定
bash
# デフォルトは3行
git diff
# 10行のコンテキスト
git diff -U10
# コンテキストなし
git diff -U0
--no-index: Git管理外のファイルを比較
bash
git diff --no-index file1.txt file2.txt
Gitリポジトリ外のファイル同士も比較できます。
実践的な使い方
コミット前の確認
bash
# 1. 未ステージングの変更を確認
git diff
# 2. ステージング
git add .
# 3. ステージング済みの内容を確認
git diff --cached
# 4. 問題なければコミット
git commit -m "Update feature"
プルリクエストのレビュー
bash
# mainブランチとの差分を確認
git diff main
# 変更されたファイルの一覧
git diff main --name-only
# 統計情報
git diff main --stat
特定のコミットの変更を確認
bash
# 特定のコミットで何が変わったか
git diff commit-hash^..commit-hash
# または
git show commit-hash
マージ前の確認
bash
# featureブランチをマージした場合の差分
git diff ...feature
# コンフリクトが起きそうな箇所を確認
git diff --name-only ...feature
ファイルの履歴を追跡
bash
# 現在と3つ前のコミットでファイルがどう変わったか
git diff HEAD~3 -- src/app.js
差分の読み方
基本的な記号
diff
diff --git a/src/app.js b/src/app.js
index a1b2c3d..e4f5g6h 100644
--- a/src/app.js
+++ b/src/app.js
@@ -10,7 +10,7 @@ function login(user) {
if (!user) {
return null;
}
- return user.name;
+ return user.username;
}
---: 古いファイル(a/)+++: 新しいファイル(b/)@@: チャンク情報(変更箇所の行番号)-: 削除された行+: 追加された行: 変更されていない行(コンテキスト)
チャンクヘッダーの読み方
diff
@@ -10,7 +10,7 @@ function login(user) {
-10,7: 古いファイルの10行目から7行分+10,7: 新しいファイルの10行目から7行分function login(user): 変更箇所の関数名(コンテキスト)
差分の種類
作業ディレクトリ vs ステージングエリア
bash
# 未ステージングの変更
git diff
git addする前の変更を確認します。
ステージングエリア vs 最新コミット
bash
# ステージング済みの変更
git diff --cached
次のgit commitで記録される内容を確認します。
作業ディレクトリ vs 最新コミット
bash
# すべての変更(ステージング済み + 未ステージング)
git diff HEAD
コミット vs コミット
bash
# 2つのコミット間の差分
git diff commit-a commit-b
フィルタリング
特定の拡張子のみ
bash
# JavaScriptファイルのみ
git diff -- "*.js"
# TypeScriptファイルのみ
git diff -- "*.ts" "*.tsx"
特定のディレクトリのみ
bash
# srcディレクトリのみ
git diff -- src/
# 複数のディレクトリ
git diff -- src/ tests/
パスを除外
bash
# package-lock.jsonを除外
git diff -- . ':(exclude)package-lock.json'
# node_modulesを除外
git diff -- . ':(exclude)node_modules/*'
出力形式
デフォルト形式
bash
git diff
標準的なunified diff形式。
コンパクト形式
bash
# 統計情報のみ
git diff --stat
# ファイル名のみ
git diff --name-only
# ファイル名と状態
git diff --name-status
パッチファイルとして出力
bash
# パッチファイルを作成
git diff > changes.patch
# パッチを適用
git apply changes.patch
カラー表示
bash
# カラー表示を強制(パイプ使用時)
git diff --color=always | less -R
# カラー表示を無効化
git diff --color=never
他のコマンドとの組み合わせ
git statusと組み合わせる
bash
# 変更されたファイルを確認
git status -s
# 具体的な変更内容を確認
git diff
# ステージング済みの内容を確認
git diff --cached
git addと組み合わせる
bash
# 差分を確認してから追加
git diff src/app.js
git add src/app.js
# 部分的にステージング
git add -p
git logと組み合わせる
bash
# コミット履歴を確認
git log --oneline -5
# 特定のコミットの差分
git diff a1b2c3d^..a1b2c3d
git showと組み合わせる
bash
# 特定のコミットの詳細(差分も含む)
git show a1b2c3d
# これは以下と同等
git diff a1b2c3d^..a1b2c3d
よくあるパターン
パターン1: コミット前の最終確認
bash
# 1. 変更内容を確認
git diff
# 2. ステージング
git add .
# 3. ステージング済みの内容を再確認
git diff --cached
# 4. コミット
git commit -m "Add feature"
パターン2: ブランチマージ前の確認
bash
# 1. mainとの差分を確認
git diff main
# 2. 変更されたファイルを確認
git diff main --name-only
# 3. 統計情報を確認
git diff main --stat
# 4. 問題なければマージ
git checkout main
git merge feature
パターン3: 他の人の変更を確認
bash
# 1. プル
git pull
# 2. 変更内容を確認
git diff HEAD~1
# 3. 特定のファイルの詳細を確認
git diff HEAD~1 -- src/important-file.js
パターン4: リファクタリングの確認
bash
# 空白の変更を無視して実質的な変更のみ確認
git diff -w
# 単語単位で確認
git diff --word-diff
便利なテクニック
変更行数をカウント
bash
# 追加・削除された行数
git diff --stat
# または
git diff --shortstat
出力例:
plain
3 files changed, 40 insertions(+), 6 deletions(-)
特定の関数の変更のみ
bash
# 関数単位で差分を表示
git diff -U0 | grep -A5 "function_name"
バイナリファイルの差分
bash
# バイナリファイルも表示
git diff --binary
# バイナリファイルの有無のみ
git diff --name-only
リネームの検出
bash
# リネームを検出
git diff -M
# リネームの検出閾値を指定(デフォルト50%)
git diff -M90%
差分の範囲指定
2つのドット (..)
bash
git diff branch-a..branch-b
branch-bの最新コミットとbranch-aの最新コミットの差分- 単純な2つのコミット間の差分
3つのドット (...)
bash
git diff branch-a...branch-b
- 共通の祖先から
branch-bがどう変わったか - マージベースとの差分
- プルリクエストのレビューに便利
よくある間違いと対処
差分が表示されない
bash
# 原因1: すべてステージング済み
git diff # 何も表示されない
git diff --cached # ステージング済みの差分が表示される
# 原因2: 変更がない
git status # 状態を確認
差分が大きすぎる
bash
# ファイル名のみ表示
git diff --name-only
# 統計情報のみ
git diff --stat
# 特定のファイルのみ
git diff -- src/specific-file.js
空白の変更で見づらい
bash
# 空白の変更を無視
git diff -w
# 行末の空白のみ無視
git diff --ignore-space-at-eol
バイナリファイルの警告
plain
Binary files a/image.png and b/image.png differ
バイナリファイル(画像など)は差分を表示できません。
bash
# ファイル名と状態のみ確認
git diff --name-status
ベストプラクティス
1. コミット前に必ずdiffで確認
bash
# 未ステージングの変更
git diff
# ステージング後の確認
git diff --cached
# デバッグコードや不要な変更がないかチェック
2. --cachedを習慣化
bash
# git addの後は必ず確認
git add .
git diff --cached # 次のコミットに含まれる内容を確認
git commit -m "..."
3. 統計情報で全体像を把握
bash
# まず統計情報で概要を確認
git diff --stat
# 詳細が必要なファイルのみ確認
git diff -- src/specific-file.js
4. エイリアスを設定
[alias]
d = diff
dc = diff --cached
ds = diff --stat
dw = diff --word-diff
dn = diff --name-only
使用例:
bash
git d # git diff
git dc # git diff --cached
git ds # git diff --stat
git dw # git diff --word-diff
git dn # git diff --name-only
5. ページャーを活用
bash
# lessで表示(デフォルト)
git diff
# lessの操作
# - スペース: 次のページ
# - b: 前のページ
# - /pattern: 検索
# - n: 次の検索結果
# - q: 終了
diffツールを使う
外部diffツールを設定
bash
# 設定
git config --global diff.tool vimdiff
# または meld, kdiff3, opendiff など
# 使用
git difftool
# 各ファイルごとに確認
git difftool --dir-diff
VS Codeをdiffツールに設定
[diff]
tool = vscode
[difftool "vscode"]
cmd = code --wait --diff $LOCAL $REMOTE
使用例:
bash
git difftool
よくある質問
Q: diffとshowの違いは?
A:
git diff: 2つの状態の差分を比較git show: 特定のコミットの情報と差分を表示
bash
git diff HEAD~1 HEAD # 差分のみ
git show HEAD # コミット情報 + 差分
Q: ..と...の違いは?
A:
..: 2つのコミット間の直接的な差分...: 共通の祖先からの差分
bash
git diff main..feature # mainとfeatureの差分
git diff main...feature # マージベースとfeatureの差分
Q: 差分を保存したい
A: リダイレクトまたはパッチファイルとして保存します。
bash
# テキストファイルとして保存
git diff > changes.txt
# パッチファイルとして保存
git diff > changes.patch
# 適用
git apply changes.patch
Q: 特定の行のみの差分を見たい
A: grepと組み合わせます。
bash
git diff | grep -A5 -B5 "検索パターン"
まとめ:覚えておくべきコマンド
bash
# 基本
git diff # 未ステージングの変更
git diff --cached # ステージング済みの変更
git diff HEAD # すべての変更
# ファイル指定
git diff file.js # 特定のファイル
git diff -- src/ # 特定のディレクトリ
# コミット間
git diff commit-a commit-b # 2つのコミット間
git diff main..feature # ブランチ間
# 表示形式
git diff --stat # 統計情報
git diff --name-only # ファイル名のみ
git diff --name-status # ファイル名と状態
# オプション
git diff -w # 空白を無視
git diff --word-diff # 単語単位
git diff -U10 # コンテキスト行数
# よく使う組み合わせ
git diff --cached --stat # コミット前の統計確認
git diff main --name-only # ブランチ間のファイル一覧
典型的なワークフロー
bash
# 1. 変更内容を確認
git diff
# 2. ステージング
git add .
# 3. 最終確認
git diff --cached
# 4. コミット
git commit -m "Update feature"