TAKASHI YAMASHINA software engineer

git diffの使い方 - 変更の差分を確認

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

--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;
 }

チャンクヘッダーの読み方

diff
@@ -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

3つのドット (...)

bash
git diff branch-a...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:

bash
git diff HEAD~1 HEAD  # 差分のみ
git show HEAD         # コミット情報 + 差分

Q: ..と...の違いは?

A:

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"