Git バージョン管理 ・ 中級差分と経緯を調べる(diff・blame)
「何が変わったのか」「なぜこう変えたのか」を調べる力は、コードを書く力と同じくらい大事です。git diffで作業ツリー・ステージ・直前コミットの3面の差分を見比べ、git logで流れをたどり、git blameで各行の由来を追う方法を身につけます。犯人探しではなく、経緯を理解するための調査術です。
コードを触っていると「今どこを変えたんだっけ」「このコミット、何を直したんだっけ」と分からなくなる瞬間が必ず来る。そのたびにファイルを目で見比べるのは非効率だし、見落としも起きる。
特にチームでコードを触っていると、自分が書いていない箇所に「なぜこんな実装になっているのか」と疑問を持つ場面が頻繁にある。そのときに頼りになるのが、変更の記録をそのまま調べられるGitの調査コマンド群だ。
Gitには変更内容を正確に映し出す道具が揃っている。今の変更を見るなら git diff、過去の流れを見るなら git log、この1行を最後に触ったのは誰かを見るなら git blame だ。この3つを使い分けられると、コードの経緯を追う速度が一段上がる。
🔗たとえdiff は「今と直前の写真を重ねて透かして見る」道具、log は「アルバムを時系列にめくる」道具、blame は「各ページの余白に書かれたメモの筆跡を辿る」道具、というイメージだ。
🔍 diffの3つの面
git diff は何も付けずに実行すると、「作業ツリー」と「ステージング(git addした内容)」の差分を表示する。つまり、まだ git add していない変更だけが見える。
git diff --staged(または --cached)を付けると、「ステージング」と「直前のコミット」の差分が見える。つまり、git add済みでこれからコミットされる内容だけが見える。
git diff HEAD を付けると、「作業ツリー」と「直前のコミット」の差分、つまりステージの有無に関係なく今の全変更が見える。
💡ポイント「addした分だけ確認したい」なら --staged、「addしていない分も含めて全部見たい」なら HEAD 付き、と覚えると迷わない。
▶例addする前に変更内容を見る
$ git diff
diff --git a/app.js b/app.js
-console.log("debug")
+console.log("ready")
✓コツdiffの出力で先頭に - が付く行は「削除された行」、+ が付く行は「追加された行」を表す。変更なしの行は何も付かずそのまま表示され、前後の文脈として一緒に出てくる。
📜 履歴を流れで見る
git log は1コミットごとに詳細を表示するが、そのままだと縦に長く見づらい。実務では git log --oneline --graph を使うことが多い。
▶例1行ずつ、分岐の形も見えるように表示する
$ git log --oneline --graph
* 8b2e4f1 (HEAD -> main) バリデーション修正
* 3a9f1c2 ログイン画面を追加
| * 7c1d0a9 (feature/nav) ナビ調整
|/
* 1f0e2b3 初期コミット
各コミットの中身そのもの(差分)まで見たいときは git log -p を使う。-p は patch(差分)の略で、コミットごとに何が変わったかがそのまま表示される。
✓コツ特定のファイルの歴史だけ知りたいときは git log -p ファイル名 のように末尾にパスを足すと、そのファイルに関係するコミットだけに絞り込める。
🕵️ blame=各行の由来を追う
git blame ファイル名 を実行すると、そのファイルの各行の左側に、その行を最後に変更したコミットのハッシュ・作成者・日付が表示される。
▶例各行の由来を調べる
$ git blame config.js
3a9f1c2 (yamada 2026-06-10 12) const TIMEOUT = 3000;
8b2e4f1 (suzuki 2026-07-01 13) const RETRY = 3;
⚠つまずきblame という単語は「非難する」という意味だが、実務での使い方は「犯人探し」ではない。「なぜこの1行がこの値になっているのか」「この変更の意図は何だったのか」を、その行を書いた本人やコミットメッセージにたどり着いて理解するための調査だ。
🔗たとえblame は指差して責めるためではなく、料理のレシピに残った「なぜこの手順を入れたか」というメモを遡って読むようなものだ。理由が分かれば、安心して次の変更ができる。
由来のコミットが分かったら、そのコミットの全体像を git show コミットハッシュ で見ると、前後の変更もまとめて確認できる。
▶例気になったコミットの中身をまとめて見る
$ git show 3a9f1c2
commit 3a9f1c2...
Author: yamada <yamada@example.com>
Date: Wed Jun 10 12:00:00 2026 +0900
タイムアウト値を調整
diff --git a/config.js b/config.js
-const TIMEOUT = 1000;
+const TIMEOUT = 3000;
💡ポイント「今何が変わったか」は diff、「どんな流れでここまで来たか」は log、「この1行の由来」は blame。3つを組み合わせれば、コードの経緯はほぼ追い切れる。
調査は書く作業と同じくらい価値がある。何かおかしいと思ったとき、まず経緯を調べる癖をつけておくと、無用な書き直しや、同じ間違いの繰り返しを防げるようになる。
特に、他人のコードを触るときほどこの調査が役に立つ。いきなり書き換える前に diff・log・blame で背景を押さえておくと、意図を壊さずに直せる確率がぐっと上がる。
🧭 blameの先が「移動しただけ」だったら
git blame で調べた結果、その行を最後に触ったコミットが「フォルダ構成を整理しました」のような、内容とは無関係な移動・整形のコミットだったという経験をすることがある。
これは、ファイルの移動やインデントの一括修正でも、その行に触れた扱いになるために起きる。本当に知りたいのは「なぜこの値になったか」という、もっと昔の意味のある変更のはずだ。
⚠つまずきgit blame -w というオプションを使うと、空白の変更だけの行は無視して、それより前の実質的な変更コミットまでさかのぼって表示してくれる。整形コミットに埋もれて調査が止まってしまうときに使うと便利だ。
▶例空白の変更を無視してさかのぼる
$ git blame -w config.js
3a9f1c2 (yamada 2026-06-10 12) const TIMEOUT = 3000;
📐 diffの読み方をもう少し詳しく
diffの出力には @@ -1,3 +1,3 @@ のような行が挟まることがある。これはハンク(変更のかたまり)の位置情報で、「元のファイルの1行目から3行分」「新しいファイルの1行目から3行分」が対応することを示している。
この数字を無理に覚える必要はない。慣れないうちは、-(削除)行と+(追加)行のペアだけを追いかければ、何がどう変わったかは十分に読み取れる。
🔎 探したい変更をキーワードで絞る
履歴が長くなってくると、目当ての変更をスクロールだけで探すのは大変になる。git log には検索用のオプションもいくつか用意されている。
コミットメッセージの中身で絞り込みたいときは git log --grep="タイムアウト" のようにキーワードを指定する。特定のコード片がいつ追加・削除されたかを追いたいときは git log -S"TIMEOUT" のように -S オプションでその文字列を含む変更だけに絞れる。
▶例メッセージにキーワードを含むコミットだけ表示
$ git log --grep="タイムアウト" --oneline
3a9f1c2 タイムアウト値を調整
✓コツ「あの修正、いつ入ったんだっけ」と探すとき、まず --grep で日本語のコミットメッセージから当たりをつけ、見つからなければ -S でコードそのものから探す、という2段構えにすると効率がよい。
調べる道具を知っているだけで、コードに対する不安はかなり減る。「分からなかったら聞く」の前に「まず自分で調べてみる」を選べるようになるのが、これらのコマンドを覚える一番の価値だ。
この項目に出てくる用語
3つの領域(作業ツリー・ステージ・HEAD)みっつのりょういきGitの変更が通る3つの段階。編集中のファイル・addした内容・直前コミットの3つを指す。
blame(行ごとの由来調査)ぶれいむファイルの各行が最後にどのコミットで変更されたかを調べる調査方法。
パッチ(差分の形式)ぱっち変更前後の違いを、行の追加・削除として表した差分データのこと。
関連コマンド
▶ 学習アプリでこの続きを学ぶ・演習する