意味の分からない分岐が書かれたコードを前に、消していいものか判断できず、履歴からたどろうとしている保守運用の担当者

git blameで「なぜこのコードか」を追う|履歴の読み方

改修の依頼を受けて、久しぶりにそのファイルを開く。 直したい処理のすぐ横に、意味の分からない分岐がひとつ。添えられているコメントは「暫定対応」の4文字だけ。

消していいのか、残すべきなのか。判断できないまま、手が止まる。

こういう時間、けっこう長いですよね。しかも、この行を書いた人はもう社内にいない。聞ける相手がいない。

これは、あなたの読解力の問題ではありません。「なぜこう書いたか」はコードには書かれない——その事情はコードの外に置かれて、時間が経つと拾えなくなる、というだけの話です。この記事では、その事情を履歴からたどり直す順番を、一緒に整理します。

結論:たどる順番は3つです。①その行を入れたコミットを git blame で特定するgit show でそのコミットのメッセージと差分を丸ごと読む③それでも分からなければ、コミットの日付を手がかりにコードの外(チケット・メール・障害記録)を探す。この順で降りていって、それでも分からない行は、消さずに「分からなかった」と書き足して残す。それも立派な調査結果です。

なぜ「なぜこのコードか」は消えてしまうのか

書いた本人にとっては、そのとき理由が明らかでした。だからコメントを書く必要を感じなかった。それだけのことが多いです。

なので、最初にやるのは「読んで理解しようとすること」ではありません。その行が生まれた瞬間まで戻ることです。理由は、たいていその瞬間の近くに落ちています。

ステップ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行そのものよりも、その周りで一緒に何が変わったかです。

もう少し広く見たいときは、次の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. 触らずに済むなら、触らない。今回の改修に関係しないなら、そのまま置いておいて構いません。「気持ち悪いから消す」は、いちばん事故が起きやすい動機です。
  2. 触るなら、影響の範囲を先に見る。その分岐が効いている条件を洗い出してから手を入れます(改修の影響範囲を見落とさない調査の順番)。
  3. 消すなら、戻せる形で。削除ではなくコメントアウトにして、日付・自分の名前・「経緯不明のため様子見」を書き添える。テストが無いコードなら、テストのないコードを安全に改修する進め方の手順と組み合わせてください。
  4. 一度に消さない。1つ消して、しばらく様子を見る。まとめて消すと、何が原因で何が起きたのか分からなくなります。

なお、git blame の日時や作者名は、リポジトリの移行や履歴の作り直しで実態とズレていることがあります。ここまでの手順で得られるのは「調査の手がかり」であって、確定した事実ではありません。本番の挙動に関わる判断をするときは、必ず検証環境で動きを確かめてから進めてください。

調べたことを、次の人に1行だけ残す

ここが、この記事でいちばんお伝えしたいところです。

30分かけてたどった経緯は、書き留めなければ30分後に消えます。そして半年後、同じ行の前で、また誰かが同じ30分を使います。その誰かは、たぶん自分です。

残し方は、大げさでなくて構いません。

// 2021-03-11 特定店舗の税率が別集計だったため暫定対応(チケット #482)。
// 2026-08-15 現在も対象店舗あり。恒久対応は未実施。(確認:森下)

コードのそばに1行。それが難しければ、ドキュメントの更新ルールで決めた置き場所に1行。

分からなかったことも、同じ価値があります。「2026-08-15時点で経緯を追ったが、コミットメッセージ・チケットともに手がかり無し」——これが書いてあれば、次の人は同じ道を掘り返さずに済みます。調査は、結論が出なくても無駄になりません。

明日やること:気になっている1行を1つだけ追う

30分あれば、最初の1周が終わります。

  1. 前から気になっているファイルを1つ開き、その行の番号を控える
  2. git blame -w -L <行番号-5>,<行番号+5> <ファイル> を打って、コミットのハッシュと日付を書き出す。
  3. git show <ハッシュ> で、メッセージと、一緒に変わったファイルを眺める。
  4. 分からなければ、その日付でチケットとメールを検索してみる。10分で切り上げて構いません。
  5. 分かったこと・分からなかったことを、コードのそばに1行書き足す。

これで1周です。全部のファイルでやる必要はありません。次の改修で触る場所だけで十分です。

コードの経緯を追うときのチェックリスト

上から順に、できたものにチェックを入れてください。全部そろわなくても大丈夫です。

よければ、こちらも

この調査の前後で読むと、つながりが見えやすいものを置いておきます。

気になっていたコードの経緯をたどり終えて、判断がついたことに安心している保守運用の担当者

理由の分からないコードを前に手が止まるのは、慎重だからです。よく分からないまま消してしまう人より、ずっと現場に向いています。

そして、あなたが今日たどった30分は、あなたのために使われるだけではありません。1行のコメントに変えておけば、次にこのファイルを開いた人の30分になります。誰にも褒められない仕事ですが、確かにシステムを読みやすくしています。

まずは、いちばん気になっている1行から。git blame を1回打ってみるところで、十分です。

ほかの実務ヒントは記事一覧からどうぞ。保守運用の小さな備えを、メールでも少しずつお届けしています。

関連用語