
git blameで「なぜこのコードか」を追う|履歴の読み方
改修の依頼を受けて、久しぶりにそのファイルを開く。 直したい処理のすぐ横に、意味の分からない分岐がひとつ。添えられているコメントは「暫定対応」の4文字だけ。
消していいのか、残すべきなのか。判断できないまま、手が止まる。
こういう時間、けっこう長いですよね。しかも、この行を書いた人はもう社内にいない。聞ける相手がいない。
これは、あなたの読解力の問題ではありません。「なぜこう書いたか」はコードには書かれない——その事情はコードの外に置かれて、時間が経つと拾えなくなる、というだけの話です。この記事では、その事情を履歴からたどり直す順番を、一緒に整理します。
結論:たどる順番は3つです。①その行を入れたコミットをgit blameで特定する、②git showでそのコミットのメッセージと差分を丸ごと読む、③それでも分からなければ、コミットの日付を手がかりにコードの外(チケット・メール・障害記録)を探す。この順で降りていって、それでも分からない行は、消さずに「分からなかった」と書き足して残す。それも立派な調査結果です。
なぜ「なぜこのコードか」は消えてしまうのか
書いた本人にとっては、そのとき理由が明らかでした。だからコメントを書く必要を感じなかった。それだけのことが多いです。
- 理由は当時の会話の中にあった:電話で言われた、口頭で決まった、チャットで流れた。コードの外にあるものは、コードと一緒には引き継がれません。
- 急ぎの対応だった:障害の最中に入れた1行に、丁寧な説明を書く余裕はありません。「暫定対応」と書けただけでも、当時としては十分でした。
- 記録の置き場が変わった:使っていた課題管理ツールが変わった、共有フォルダが整理された、メールアカウントが消えた。理由は書かれていたのに、器のほうが先に無くなることもあります。
- 一括で作り直された:フォーマッタをかけた、フレームワークを入れ替えた。そのときに、履歴の見た目が上書きされてしまうことがあります(この対処は後で触れます)。
なので、最初にやるのは「読んで理解しようとすること」ではありません。その行が生まれた瞬間まで戻ることです。理由は、たいていその瞬間の近くに落ちています。
ステップ1:その行を入れたコミットを特定する

git blame は、ファイルの各行を「最後に変更したコミット」と結びつけて表示するコマンドです。犯人捜しの道具のような名前ですが、実際の使いどころは「この行の出どころを聞く」ことにあります。
まずは、気になっている行の周辺だけを見ます。ファイル全体を出すと量に押し流されるので、行番号で絞るのがコツです。
# 120行目から140行目だけを見る
git blame -L 120,140 app/Http/Controllers/OrderController.php
出力は、1行ごとに次の形で並びます。
a1b2c3d4 (yamada 2021-03-11 18:42:07 +0900 128) if ($order->shop_id === 17) {
左から、コミットのID(ハッシュ)/変更した人/日時/行番号/その行の中身です。見たいのは、いちばん左のハッシュと日時。「2021年3月11日の夕方に入った1行」まで分かれば、ステップ1は終わりです。
「全部同じコミットになる」ときの対処
やってみると、対象の行だけでなくファイル中の全行が同じコミット・同じ日付になっていることがあります。これは、そのコミットで一括インポートや一斉整形が行われた合図です。
そのままでは何も分からないので、ノイズを取り除きながら見ます。
# 空白・インデントだけの変更を無視する
git blame -w -L 120,140 <ファイル>
# 行の移動やコピーも追いかける(-C を重ねるほど広く探す)
git blame -w -M -C -C -L 120,140 <ファイル>
# 一斉整形のコミットを、名指しで無視する
git blame --ignore-rev <整形コミットのハッシュ> -L 120,140 <ファイル>
-w は空白の変更を、-M は同じファイル内での行の移動を、-C は別ファイルからのコピーを、それぞれ「その行の起源ではない」として読み飛ばしてくれます。整形コミットが何度もあるなら、そのハッシュを1行ずつ書いたファイルを用意して、リポジトリ全体で常に無視させることもできます。
# 無視したいコミットのハッシュを1行ずつ書いておく
echo "<整形コミットのハッシュ>" >> .git-blame-ignore-revs
# 以後 blame するとき自動で読み込ませる
git config blame.ignoreRevsFile .git-blame-ignore-revs
これでも全部が1つのコミットに集まるなら、それはGitに載せる前の履歴が存在しないということです。そのときはステップ3へ飛んでください。コードの外を探すほうが早いです(そもそもGitに載っていない場合は、バージョン管理なしのソースをGitに載せる手順から)。
ブラウザや編集ソフトでも見られます
コマンドが手に馴染んでいなくても大丈夫です。GitHub・GitLab などのホスティングサービスにはファイルごとに blame の表示があり、行をクリックするとそのコミットへ飛べます。VS Code などのエディタでも、拡張機能を入れると行の横に「誰がいつ」を薄く表示してくれます。
普段の調査は画面で、絞り込みが必要になったらコマンドで——この使い分けで十分です。道具は、手が動くほうを選んでください。
ステップ2:そのコミットを丸ごと読む
ハッシュが分かったら、次はそのコミットを開きます。ここがいちばん収穫の多い場所です。
git show a1b2c3d4
git show は、コミットメッセージと、そのコミットの差分すべてを出します。見てほしいのは、目当ての1行そのものよりも、その周りで一緒に何が変わったかです。
- 同じコミットで設定ファイルも変わっていれば、環境まわりの対応だったと分かります。
- テストが一緒に足されていれば、何を防ぎたかったかがテスト名に書いてあります。
- 複数のファイルにまたがって同じ条件が足されていれば、その場しのぎではなく意図のある対応だったと分かります。
- メッセージが「fix」の3文字でも、日時と、一緒に変わったファイルの組み合わせは残ります。それが次の手がかりになります。
もう少し広く見たいときは、次の3つが効きます。
# このファイルの変更履歴を一覧で(--follow でファイル名の変更もたどる)
git log --oneline --follow -- app/Http/Controllers/OrderController.php
# 「shop_id」という文字列が足された/消されたコミットだけを拾う
git log -S"shop_id" --oneline -- app/
# 128行目付近だけの変遷を、差分つきで古い順にたどる
git log -L 120,140:app/Http/Controllers/OrderController.php
とくに -S(pickaxe と呼ばれます)は、その値や関数名が「いつ現れて、いつ消えたか」を教えてくれます。謎の定数やマジックナンバーの出どころを探すときに、いちばん早い道です。
git log -L は行範囲の変遷をそのまま見せてくれるので、「最初はもっと素直な処理だったのに、3回の修正でこうなった」といった経緯が一目で分かることがあります。読む量は増えますが、判断の材料としては濃いです。
ステップ3:コミットの外を探す
コミットメッセージが「修正」「対応」だけで終わっていることは、珍しくありません。そこで詰まったら、日付を鍵にして、コードの外を探します。
手に入っているのは「2021年3月11日 18時42分」という時刻です。これは意外なほど強い検索条件です。
- 課題管理・チケット:その日の前後で作られたチケット、完了になったチケットを見る。番号がコミットメッセージに書いてあれば一直線です。
- メール・チャット:同じ日付のやりとりを検索する。「〇〇店だけ表示がおかしい」といった件名が見つかれば、それが分岐の理由です。
- 障害の記録・振り返り:夕方から夜のコミットは、障害対応の最中に入ったものである確率が高いです。障害対応の履歴を残す仕組みや振り返り(ポストモーテム)の記録があれば、そこに事情が書かれていることがあります。
- リリース・変更の記録:変更管理台帳やリリース手順書に、その日の作業として残っていることがあります。
- 問い合わせの対応ログ:お客様や社内から来た依頼が起点なら、問い合わせ対応の記録に元の言葉が残っています。
ここまで来ると、コードを読む作業というより、資料をたぐる作業になります。時間もかかります。ただ、改修の判断が変わるほどの発見は、たいていこの層にあります。「特定の取引先だけ仕様が違う」といった話は、コードのどこにも書かれていないからです。
社内に当時を知っている人がいるなら、聞くのがいちばん早いです。そのときは「なぜこんな書き方を」ではなく、「この日にこういう対応をされていたようなのですが、覚えていますか」と、日付と事実を添えて聞くと思い出してもらいやすくなります。
それでも分からない行を、どう扱うか
正直に言えば、全部は分かりません。半分たどれれば上出来です。
そこで大事になるのが、「分からない」を「たぶん要らない」に読み替えないことです。理由が見つからないのは、理由が無かったからとは限りません。記録のほうが先に消えただけかもしれない。
判断に迷ったときは、この順番で考えると落ち着きます。
- 触らずに済むなら、触らない。今回の改修に関係しないなら、そのまま置いておいて構いません。「気持ち悪いから消す」は、いちばん事故が起きやすい動機です。
- 触るなら、影響の範囲を先に見る。その分岐が効いている条件を洗い出してから手を入れます(改修の影響範囲を見落とさない調査の順番)。
- 消すなら、戻せる形で。削除ではなくコメントアウトにして、日付・自分の名前・「経緯不明のため様子見」を書き添える。テストが無いコードなら、テストのないコードを安全に改修する進め方の手順と組み合わせてください。
- 一度に消さない。1つ消して、しばらく様子を見る。まとめて消すと、何が原因で何が起きたのか分からなくなります。
なお、git blame の日時や作者名は、リポジトリの移行や履歴の作り直しで実態とズレていることがあります。ここまでの手順で得られるのは「調査の手がかり」であって、確定した事実ではありません。本番の挙動に関わる判断をするときは、必ず検証環境で動きを確かめてから進めてください。
調べたことを、次の人に1行だけ残す
ここが、この記事でいちばんお伝えしたいところです。
30分かけてたどった経緯は、書き留めなければ30分後に消えます。そして半年後、同じ行の前で、また誰かが同じ30分を使います。その誰かは、たぶん自分です。
残し方は、大げさでなくて構いません。
// 2021-03-11 特定店舗の税率が別集計だったため暫定対応(チケット #482)。
// 2026-08-15 現在も対象店舗あり。恒久対応は未実施。(確認:森下)
コードのそばに1行。それが難しければ、ドキュメントの更新ルールで決めた置き場所に1行。
分からなかったことも、同じ価値があります。「2026-08-15時点で経緯を追ったが、コミットメッセージ・チケットともに手がかり無し」——これが書いてあれば、次の人は同じ道を掘り返さずに済みます。調査は、結論が出なくても無駄になりません。
明日やること:気になっている1行を1つだけ追う
30分あれば、最初の1周が終わります。
- 前から気になっているファイルを1つ開き、その行の番号を控える。
git blame -w -L <行番号-5>,<行番号+5> <ファイル>を打って、コミットのハッシュと日付を書き出す。git show <ハッシュ>で、メッセージと、一緒に変わったファイルを眺める。- 分からなければ、その日付でチケットとメールを検索してみる。10分で切り上げて構いません。
- 分かったこと・分からなかったことを、コードのそばに1行書き足す。
これで1周です。全部のファイルでやる必要はありません。次の改修で触る場所だけで十分です。
コードの経緯を追うときのチェックリスト
上から順に、できたものにチェックを入れてください。全部そろわなくても大丈夫です。
- 対象の行番号を絞って
git blame -Lを実行したか - 全行が同じコミットになっていないか確認したか(なっていたら
-w-Cを足す) - 一斉整形のコミットが混ざっていないか見たか(
--ignore-rev) -
git showでコミットメッセージと差分全体を読んだか - 同じコミットで一緒に変わった他のファイルを見たか
- 謎の値・関数名は
git log -Sで出入りを追ったか - コミットの日付で、チケット・メール・障害記録を検索したか
- 当時を知っている人がいれば、日付を添えて聞いてみたか
- 分からない行を「要らない行」と決めつけていないか
- 消す場合、戻せる形(コメントアウト+日付・氏名)にしたか
- 分かったこと/分からなかったことを1行残したか
よければ、こちらも
この調査の前後で読むと、つながりが見えやすいものを置いておきます。
- 既存システムの改修|影響範囲を見落とさない調査の順番:経緯が分かったあと、どこまで影響するかを確かめるために。
- テストのないコードを安全に改修する進め方:戻せる形で手を入れるための、具体的な段取り。
- 触れないレガシーコードに"最初の一歩"を:手が止まってしまうコードとの、そもそもの向き合い方。
- 仕様書がないシステムの仕様を、現状から起こす進め方:1行の調査を、システム全体の理解につなげたくなったら。
- バージョン管理なしのソースをGitに載せる手順:そもそも履歴が無いときは、ここから始まります。

理由の分からないコードを前に手が止まるのは、慎重だからです。よく分からないまま消してしまう人より、ずっと現場に向いています。
そして、あなたが今日たどった30分は、あなたのために使われるだけではありません。1行のコメントに変えておけば、次にこのファイルを開いた人の30分になります。誰にも褒められない仕事ですが、確かにシステムを読みやすくしています。
まずは、いちばん気になっている1行から。git blame を1回打ってみるところで、十分です。
ほかの実務ヒントは記事一覧からどうぞ。保守運用の小さな備えを、メールでも少しずつお届けしています。