「バグを仕込んだコミットはどれだ?」「v1.2.0からv1.3.0で何が変わった?」「10コミット前と今で、どの関数が書き換わった?」——開発の振り返り・原因調査・リリースノート作成で、コミット間の差分を確認する場面は頻繁にあります。
この記事では、Gitで特定のコミット同士を比較する方法を体系的に解説します。SHA・タグ・HEAD~Nなど多彩なコミット参照、git diffとgit showの使い分け、単一コミットを親と比較する書式、パッチファイル出力、そしてgit bisect/git log --followとの連携まで、調査・レビュー・リリース管理で役立つコマンドを網羅します。
この記事で学べること
- コミットを指す8種類の参照記法(SHA・HEAD・
HEAD~N・タグ・reflog など) git diff <A> <B>の基本と表示オプションの使い分けgit showで単一コミットを親との差分で確認する方法- タグ同士の比較(リリース間の変更把握)
- パッチファイルへの出力(
format-patch/リダイレクト) - 特定ファイル・ディレクトリに絞ったコミット間diff
- バグ調査・リリースノート作成・バックポート検討で使う実践シナリオ
コミットを指す参照方法いろいろ
「コミットA」をコマンドに渡すとき、SHA(ハッシュ値)以外にも様々な指定ができます。目的に応じて使い分けると手早く比較が書けます。
ポイント:SHAはコピペで確実ですが、人が読み書きするならHEAD~5やタグが直感的です。調査スクリプトなどではブレない参照(SHA・タグ)を使い、手動の検証では相対参照を活用するとスピードと安全性のバランスが取れます。
基本:git diff A B でコミット間を比較
2つのコミットを指定すれば、それぞれのツリー(スナップショット)を直接比較します。ブランチ間の2ドット(A..B)と同じ意味で、空白区切りでもドット付きでも結果は同じです。
# SHA指定
git diff a1b2c3d e4f5g6a
# 相対参照
git diff HEAD~5 HEAD
# タグ同士(v1.2.0 と v1.3.0 の差分)
git diff v1.2.0 v1.3.0
# 現在とN日前
git diff "HEAD@{yesterday}" HEAD
# ブランチの先端と固定コミット
git diff a1b2c3d main
# 2ドットは空白区切りと同義
git diff HEAD~3..HEAD
A..B と A…B の使い分け
A..B(2ドット):A と B の先端同士を直接比較(git diff A Bと同じ)A...B(3ドット):merge-base と B の差分(PR相当の見え方)- コミット同士の比較は通常2ドット。3ドットが活きるのはブランチ間比較のときが多い
- 詳細はブランチ間の差分を比較する方法を参照
単一コミットを確認する:git show
git showは指定コミット1つを「親コミットとの差分」として表示します。「このコミットが何をしたのか」を素早く見たいときに最適です。内部的にはgit diff <commit>^ <commit>と等価です。
# 最新コミットを表示 git show # 特定コミットを表示 git show a1b2c3d # 相対指定 git show HEAD~2 # タグが指すコミットを表示 git show v1.2.0 # 特定ファイルの変更だけ git show HEAD -- src/auth.py # 変更行だけで統計 git show --stat HEAD # メッセージを省略して差分だけ git show --format= HEAD # コミットメッセージだけ git show -s --format=%B HEAD
ポイント:「このコミットで何が変わった?」を1コマンドで確認したいとき、git showが最も直感的です。git diff HEAD~1 HEADでも同じ結果ですが、コミットメッセージやメタ情報も同時に表示されるため、レビューではgit showが見やすいです。
親コミットとの差分を見る
「このコミット単体がリポジトリに何を加えたか」を確認する書き方は複数あります。挙動と読みやすさの両方で、好みの書式を選んでください。
# パターン①: git show(最も簡潔) git show a1b2c3d # パターン②: 親(^)を明示指定 git diff a1b2c3d^ a1b2c3d # パターン③: 相対参照で直前と比較 git diff HEAD~1 HEAD # パターン④: 2ドット記法 git diff HEAD~1..HEAD # パターン⑤: 親が複数(マージコミットの場合) git show a1b2c3d^1 # 第1親 git show a1b2c3d^2 # 第2親
マージコミットの diff は注意
マージコミット(2つ以上の親を持つ)にgit showを使うと、デフォルトでは「結合された差分」(combined diff)が表示されます。片方の親だけと比較したい場合は^1・^2で明示します。マージコミット打ち消しと合わせてmergeコミットを取り消して履歴を元に戻す方法も参照してください。
diff出力を目的別に整える
# ファイル名だけ列挙 git diff --name-only v1.2.0 v1.3.0 # 変更種別付き(A/M/D/R) git diff --name-status v1.2.0 v1.3.0 # 変更規模(行数)を集計 git diff --stat v1.2.0 v1.3.0 # サマリーだけ1行で git diff --shortstat v1.2.0 v1.3.0 # ワード単位の差分(文書・READMEに便利) git diff --word-diff v1.2.0 v1.3.0 # 空白無視 git diff -w v1.2.0 v1.3.0 # 前後10行ずつコンテキスト git diff -U10 v1.2.0 v1.3.0 # rename検出強化(大きな変更を伴ってもrenameと認識) git diff -M50% v1.2.0 v1.3.0
特定ファイル・ディレクトリに絞り込む
# 特定ファイル git diff v1.2.0 v1.3.0 -- src/auth.py # ディレクトリ git diff v1.2.0 v1.3.0 -- src/ # globパターン git diff v1.2.0 v1.3.0 -- "*.js" "*.ts" # 除外指定 git diff v1.2.0 v1.3.0 -- . ":(exclude)tests/"
ファイル指定の詳細はgit diff でファイル指定する方法を参照してください。
パッチファイル(patch)として出力する
差分を他の環境に渡したり、メールでレビューを依頼したりするときはパッチファイル形式が便利です。git format-patchでコミット単位の綺麗なパッチ、リダイレクトで手軽な diff ファイル、と用途で使い分けます。
# 差分を単純ファイル化 git diff v1.2.0 v1.3.0 > release-1.2-to-1.3.patch # コミット単位の整ったパッチ(mbox形式、git am で適用可) git format-patch v1.2.0..v1.3.0 # → 0001-xxx.patch, 0002-xxx.patch ... が生成される # 直近3コミットをパッチ化 git format-patch -3 # 出力先フォルダ指定 git format-patch v1.2.0..v1.3.0 -o patches/ # パッチを他リポジトリで適用(format-patch 経由) git am patches/0001-xxx.patch # 単純diffから適用 git apply release-1.2-to-1.3.patch
ポイント:format-patchはコミットメッセージ・作者情報を保持するため、別リポジトリに履歴を綺麗に移植できます。単純diffリダイレクトはファイル差分だけで、コミット情報は含まれません。目的に応じて選びましょう。
実践シナリオ
シナリオ① リリース間の変更を把握(リリースノート作成)
# 変更ファイル一覧 git diff --name-status v1.2.0 v1.3.0 # コミットメッセージ一覧 git log --oneline v1.2.0..v1.3.0 # 規模感の集計 git diff --shortstat v1.2.0 v1.3.0 # 著者別コミット集計 git shortlog v1.2.0..v1.3.0 # 特定ディレクトリの変更だけ git diff v1.2.0 v1.3.0 -- src/api/
シナリオ② バグ発生コミットの特定
# 動いていた時点と壊れた時点を指定してbisect開始 git bisect start git bisect bad HEAD git bisect good v1.2.0 # Gitが中間コミットをcheckoutするので、動作確認 # 良ければ: git bisect good / 悪ければ: git bisect bad # 繰り返すとバグ混入SHAが特定される # 特定されたコミットの変更内容を確認 git show <混入SHA> # 親との比較で原因コードを精査 git diff <混入SHA>^ <混入SHA> -- src/ # bisect終了 git bisect reset
bisectの詳しい使い方はbisectでバグを仕込んだコミットを特定する方法を参照。
シナリオ③ 回帰調査(regression の原因追跡)
# 特定ファイルを触ったコミットだけ抽出 git log --oneline --follow -- src/auth.py # 不具合発生前後で特定ファイルの変化を見る git diff <疑わしいSHA>^ <疑わしいSHA> -- src/auth.py # 該当関数を含む変更を検索 git log -S "authenticate" --oneline -- src/auth.py # -S=pickaxe 検索:指定文字列の追加/削除を含むコミットを絞り込む # その変更を確認 git show <SHA> -- src/auth.py
シナリオ④ バックポート前の下見
# 本線と hotfix ブランチの差分コミット一覧 git log --oneline main..hotfix/urgent # 取り込み候補の1コミットを精査 git show <SHA> # 個別ファイルの diff でリスク評価 git diff main <SHA> -- src/critical.py # 問題なければ cherry-pick git switch main git cherry-pick <SHA>
GUI・IDEでのコミット比較
主要ツールでの比較
- VS Code / Cursor:GitLensの
Open Changes with...、Timelineビューで任意2点の比較 - JetBrains:Gitログで2コミットをCtrl+選択 → Compare Versions
- SourceTree:コミット2つをShift+選択 → 右側に差分表示
- GitHub Web:
https://github.com/{user}/{repo}/compare/{SHA1}...{SHA2} - gitk:
gitk --allでGUIグラフ+クリックで差分表示 - git difftool:お好みのGUI差分ツールを呼び出し可能
GitHub Web の compare URL
# SHA同士 or タグ同士のURL形式 open "https://github.com/user/repo/compare/v1.2.0...v1.3.0" open "https://github.com/user/repo/compare/a1b2c3d...e4f5g6a" # 単一コミットを見るなら /commit/ 形式 open "https://github.com/user/repo/commit/a1b2c3d"
やってはいけない落とし穴
順序を逆にして「マイナス差分だらけ」と困惑する
git diff A Bは「AからBへの変更」を表示します。古いコミットを右に、新しいコミットを左に置くと、追加されたコードがマイナス扱いで出てきて混乱します。「古い→新しい」の順で書くのが自然です:git diff v1.2.0 v1.3.0(v1.2.0→v1.3.0の変化を見る)。
SHAを短くしすぎてambiguousエラー
3〜4文字ではリポジトリに複数のコミットがマッチすることがあります。fatal: ambiguous argument 'abc'が出たらgit log --onelineで表示される7〜8文字を使うのが安全です。大規模プロジェクトでは10文字以上を推奨。
merge commit の diff で混乱する
マージコミットには親が2つあるため、git showのデフォルト動作は「combined diff」という特殊な表示になります。通常のdiffが見たいならgit show -mまたはgit show --first-parentで親指定を明示しましょう。rebaseで履歴をリニア化しておくとこの問題に遭遇しなくなります。
git diff と git show を混同する
git diff A(引数1つ)は「AのツリーとHEADの作業ツリー比較」になり、意図した「Aの変更内容」は表示されません。単一コミットの変更を見るならgit show A、2コミット間を比較するならgit diff A B、と明確に使い分けてください。
reflog期限切れのコミットと比較しようとする
HEAD@{2.months.ago}のようなreflog指定は、reflog(既定90日)を超えると参照不能になります。「過去の特定時点に戻りたい」なら、重要ポイントでタグを打っておくとずっと比較できる状態を保てます。タグ運用はタグ(tag)の使い方を参照。
よくある質問
git showが便利です。コミットメッセージ・作者・日時も一緒に表示され、親コミットとの差分を自動的に取ってくれます。git diff HEAD~1 HEADと等価ですが、入力がシンプルで読みやすくなります。git log --oneline v1.2.0..v1.3.0で一覧、git log -p v1.2.0..v1.3.0で各コミットの差分付き一覧、git diff v1.2.0 v1.3.0で累計差分、と目的で使い分けます。HEAD~Nは「N個前の祖先」、HEAD^Nは「N番目の親」を指します。マージコミットの親を選ぶときだけ^Nが必要で、通常の一本線の履歴ならHEAD~Nが直感的です。git show --name-only <SHA>またはgit diff-tree --no-commit-id --name-only -r <SHA>で取れます。変更種別(A/M/D)も欲しいなら--name-statusを使いましょう。git log --oneline v1.2.0..v1.3.0でコミット一覧、git shortlog v1.2.0..v1.3.0で著者別集計、git diff --stat v1.2.0 v1.3.0で規模感がそれぞれ一発で出ます。これらを整形してリリースノート本文にするのが定番です。git format-patch→git am、単純な差分だけを当てたいならgit diff > file.patch→git apply file.patchです。git show -mまたはgit show --first-parent、特定親との比較ならgit diff <merge_SHA>^1 <merge_SHA>のように書きます。関連記事
- 【Git】ブランチ間の差分を比較する方法 — ブランチ同士のdiff(2ドット vs 3ドット)
- git diff でファイル指定する方法 — ファイル単位のdiff
- 【Git】addしたファイルの変更を確認する方法 — staged内容のdiff
- 【Git】bisectでバグを仕込んだコミットを特定する方法 — 差分比較の対象コミットを絞り込む手法
- 【Git】タグ(tag)の使い方 — リリース間比較の基準点
- 【Git】mergeコミットを取り消して履歴を元に戻す方法 — マージコミット特有の扱い
- 【Git】コミットの取り消し方 — 差分確認後の取り消し手順
- 【Git】よく使うgitコマンドまとめ — 日常コマンドの早見表
まとめ
- コミット参照はSHA・HEAD・HEAD~N・HEAD^・タグ・ブランチ・reflog・@{u}の8種類
- 2コミット間の内容比較は
git diff A B、単一コミット確認はgit show - 順序は「古い→新しい」で書くと差分が読みやすい
- コミット一覧は
git log A..B、統計は--stat/shortlog - パッチ化は履歴保持なら
format-patch、単純差分ならgit diff > file.patch - マージコミットは
^1・^2で親を明示すると混乱しない - bisectやpickaxe(
-S)と組み合わせると調査効率が上がる
コミット間の差分比較は、Gitの調査・レビュー・リリース管理すべての土台です。参照記法のバリエーションを覚え、git showとgit diffを目的で使い分け、format-patchやshortlogなどの補助コマンドと組み合わせれば、過去のどの時点とも素早く意味のある比較ができるようになります。タグ運用やbisectと合わせて、「いつ何が変わったか」を正確に追える履歴管理を目指しましょう。

