スキップしてメイン コンテンツに移動

【Day 30】git log -S(つるはし検索)で消えた過去の関数・定数を発掘する

Day 30 アイキャッチ
▲ 【Day 30】git log -S(つるはし検索)で消えた過去の関数・定数を発掘する
👨‍🏫
皆さん、こんにちは! 本講座の専任講師です。
前回のDay 29では、コードの犯人や導入理由を特定する「git blame & git log -L」によるコード考古学の基礎を学びました。
そして本日のDay 30は、長期運用や保守開発の現場でエンジニアが必ず一度は直面する大ピンチ——
「昔確かに存在したはずのあのC#メソッドや定数、いつ誰が消した!?」
という謎を、全リポジトリのコミット差分から瞬時に一発発掘する極意——
【git log -S(つるはし検索)で消えた過去の関数・定数を発掘する】をお届けします!
「仕様変更で半年前に削除したロジックが、法改正や方針転換で急遽また必要になった」「過去のテスト済み定数の値を確認したいが、現行コードのどこにも見当たらない……」
そんな時、何千件もあるコミットログを手作業で1件ずつめくって探していませんか?
Gitが誇る「Pickaxe(つるはし)検索」を使いこなせば、指定したテキストの「出現回数の増減(新設・削除)」を全履歴から瞬時にバイナリスキャン!
わずか0.1秒で目的のコミットを掘り当て、当時の完全なコードをピンポイントで安全にサルベージ(復元)できます!
開発現場での無駄な再車輪開発を防ぎ、生産性を劇的に高めるプロの技を完全マスターしましょう!

① 導入・本日の達成目標

ソフトウェア開発が数年続くと、不要と判断されたコードや古いインターフェースはリファクタリングで削除されていきます。
しかし現実のビジネスでは、「一度廃止された仕様が、別の顧客向けに再必要になった」「過去の複雑な計算ロジックを参考にして新機能を設計したい」という状況が日常茶飯事です。
現行コードのどこを検索しても存在しないコードを、Gitの全歴史の地層から一瞬で掘り出す最強のツールが git log -S です。

🎯 本日のゴール
  • SVN全ログ手動検索とGit Pickaxe検索の仕組みの違いと圧倒的優位性を理解する
  • git log -S(つるはし検索)で消えた関数・定数の誕生・削除コミットを一発特定する
  • git log -S(出現回数増減)と git log -G(正規表現差分検索)の決定的な違いと使い分けを完全習得する
  • 特定したコミットから git show コマンドで当時のコードをピンポイントにサルベージ(安全復元)する手順を体得する
  • C#実戦シナリオを通じて、発掘した過去ロジックを最新のC# 12構文にリファクタリングして安全に再統合するフローを確立する

② 【図解】SVN全ログ手動検索 vs Git Pickaxe検索の決定的違い

Subversion (SVN) でも過去のコミット履歴を検索することは可能でしたが、消えたコードを探す作業は過酷を極めました。

SVN全ログ手動検索 vs Git Pickaxe検索の比較
▲ 【図解①】中央サーバー通信と目視検索で重いSVN vs ローカル差分の文字列増減を0.1秒で即座に検出するGit Pickaxe検索

SVNとGitにおける過去コード探査の体験差は、以下の3点に集約されます。

比較項目 SVN 全ログ検索 Git Pickaxe検索 (git log -S)
探査スピード 中央サーバー通信必須。巨大なログの取得・検索に数分〜数十分を要する。 ローカル完全完結。数万コミットのリポジトリでも0.1秒で即時検出。
検索対象 コミットメッセージの文字列一致のみ。差分テキストの中身までは追えない。 全コミットの差分本文をスキャン。「その文字列の出現回数が増減した瞬間」を検知。
ノイズの排除 不可。コミットメッセージにメソッド名が書かれていなければ完全に空振り。 完全排除。コード内にその文字が生まれたコミットと消えたコミットだけを厳密抽出。

③ 【図解】git log -S による消えたコード発掘の3ステップ

それでは、実際に消えたC#コードを発掘して安全に復元する3ステップの黄金フローを解説します。

git log -S による消えたコード発掘の3ステップ
▲ 【図解②】①検索実行(git log -S)→ ②履歴確認(削除理由とPR特定)→ ③安全復元(git show)の完全フロー

ステップ①【検索実行】git log -S で出現・削除コミットを一撃抽出

ターミナルを開き、探したい関数名や定数名を指定して git log -S を実行します。このとき、必ず -p(パッチ表示)または --oneline を付与するのがプロの鉄則です。

# 構文: git log -S "探したい文字列" -p
$ git log -S "CalculateLegacyTax" -p -- Services/TaxService.cs

commit d7a8b92c4f1e0a8b92c4f1e0a8b92c4f1e0a8b92
Author: Suzuki Ichiro <suzuki@example.com>
Date:   Wed Apr 16 11:20:15 2025 +0900

    Refactor: 旧税率計算ロジックの廃止と新API統合 (#345)

diff --git a/Services/TaxService.cs b/Services/TaxService.cs
--- a/Services/TaxService.cs
+++ b/Services/TaxService.cs
@@ -45,18 +45,0 @@ public class TaxService
-    public decimal CalculateLegacyTax(decimal price, DateTime targetDate)
-    {
-        // 2024年以前の旧税率計算ロジック
-        if (targetDate < TaxConstants.TransitionDate)
-        {
-            return price * 0.08m;
-        }
-        return price * 0.10m;
-    }

ご覧ください!コミット d7a8b92c で、-(削除記号)と共に対象のメソッドが消去された瞬間が完全に記録されています!

ステップ②【履歴確認】なぜ削除されたのかの背景・PR番号を特定

コードが消えた瞬間が特定できたら、絶対にやってはいけないのが「何も考えずにすぐコードを復活させること」です。
コミットメッセージ Refactor: 旧税率計算ロジックの廃止と新API統合 (#345) に注目してください。
GitHub上でプルリクエスト #345 を開き、当時のレビュアーの議論や仕様書のリンクを確認します。
「なぜ削除されたのか?」「仕様上の欠陥があったのか?それとも単に当時の画面で不要になっただけなのか?」を理解して初めて、安全な再利用への道が開かれます。

ステップ③【安全復元】git show で当時のコードをピンポイント取得

当時の正常動作していたコードを取り出すには、git show コマンドに対象コミットの「直前(チルダ ~1 または キャレット ^)」を指定します。

# 削除コミットの1つ前(生きていた最後の姿)を表示・確認
$ git show d7a8b92c~1:Services/TaxService.cs

# 必要であればファイル全体ではなく該当メソッドだけを安全に別名保存
$ git show d7a8b92c~1:Services/TaxService.cs > TaxService_Old.cs
💡 一歩進んだプロの技: git restore でファイルごとサルベージ

もし完全に削除されて消滅してしまったファイル(例: Services/LegacyTaxCalculator.cs)そのものを丸ごと作業ツリーに復活させたい場合は、最新の git restore コマンドが最も安全です:
$ git restore --source=d7a8b92c~1 -- Services/LegacyTaxCalculator.cs
歴史を壊すことなく、安全に作業ツリーに未ステージングの状態で過去ファイルを取り出せます!

④ 【図解】git log -S vs git log -G の使い分け(Pickaxe vs Regex)

Gitには、差分を検索するオプションとして -S(Pickaxe)のほかに -G(Regex) が存在します。この2つの違いを正しく理解しているかどうかが、初級者とプロの分水嶺です。

git log -S vs git log -G の使い分け
▲ 【図解③】出現回数の増減を厳密抽出する-S(新設・削除特定)vs 差分行の正規表現一致を網羅する-G(影響範囲全追跡)
比較項目 git log -S "文字列"(Pickaxe) git log -G "正規表現"(Regex Diff)
検出の判定基準 ファイル全体で、その文字列の「出現回数(個数)」が増減したか コミットの差分行(+ または -)に正規表現パターンが含まれているか
行移動・インデント変更 【無視】出現回数が変わらないためノイズとして除外される 【検出】差分行に対象文字列があるためすべてヒットしてしまう
引数や実装の変更 【無視】関数名自体の個数が変わらなければヒットしない 【検出】関数のシグネチャ変更や呼び出し箇所修正を全網羅
最適なユースケース 「いつ追加されたか」「いつ誰が削除したか」を一発で特定したい時 「この関数が関与したすべての変更・呼び出し元の修正履歴」を網羅したい時
# 【-S】消えた定数や関数の誕生・削除コミットだけをピンポイント検索
$ git log -S "MAX_RETRY_COUNT" --oneline

# 【-G】TaxServiceクラスのCalculateで始まる全メソッドの変更差分を網羅検索
$ git log -G "public .* Calculate.*Tax" -p -- Services/

⑤ 【図解】C#現場でのコードサルベージ実践術

過去のコードを無事に掘り当てたら、最後は現行システムへの「安全な再統合(リファクタリング)」です。

C#現場でのコードサルベージ実践術
▲ 【図解④】過去に廃止された旧ロジックを発掘し、最新C# 12の構文に合わせて安全にリファクタリング・再統合

レガシーコード復活の3大チェックリスト

1〜2年前に書かれたC#コードを現代のシステムに復活させる際は、以下の3点を必ず確認して近代化(Modernize)しましょう。

🛡️ 過去コード安全復活のチェックリスト
  1. 同期メソッドの非同期化(async/await):
    過去の同期ブロッキングなI/O呼び出しやDBアクセスを、現行の ValueTask<T> や CancellationToken 対応に書き換える。
  2. 最新のC#言語機能の適用:
    冗長な if/else の連続を、C#の強力なパターンマッチング(switch式)にリファクタリングして可読性を向上させる。
  3. 単体テスト(xUnit / NUnit)の同時発掘:
    プロダクションコードだけでなく、git log -S "CalculateLegacyTax" -- Tests/ で当時の単体テストも同時にサルベージし、仕様の正しさを自動テストで保証する。
// 【発掘した過去コード(旧C#構文)】
public decimal CalculateLegacyTax(decimal price, DateTime targetDate)
{
    if (targetDate < TaxConstants.TransitionDate)
    {
        return price * 0.08m;
    }
    return price * 0.10m;
}

// 【C# 12仕様にリファクタリング・近代化した新コード】
public decimal CalculateModernTax(decimal price, DateOnly targetDate) => targetDate switch
{
    var d when d < TaxConstants.TransitionDateOnly => price * 0.08m,
    _ => price * 0.10m
};

⑥ まとめ&次回予告

📌 本日の最重要ポイントまとめ

  • 消えたコードは git log -S で探せ: 全コミット差分から指定文字列の出現回数が増減した瞬間だけを0.1秒でピンポイント抽出!
  • -S と -G の使い分け: 関数の誕生・削除を特定するなら -S(Pickaxe)、引数変更や影響範囲を全件追跡するなら -G(Regex Diff)。
  • 削除理由の背景確認を怠るな: コミットメッセージとPR番号から、なぜ当時削除されたのかを必ず確認して仕様不整合を防止。
  • git show で安全にサルベージ: git show <hash^>:FilePath で削除直前の完全なコードを抽出。
  • 最新C#への近代化: 発掘した過去資産をそのまま貼り付けるのではなく、最新の構文や非同期設計にアップデートして再活用。

🚀 次回予告【Day 31】

次回は、同じブランチの統合で何度も何度も同じコンフリクトを解消させられて疲弊しているエンジニアに贈る奇跡の機能——
【git rerere で過去に解決したコンフリクトを全自動解決させる魔法】をお届けします!
「Reuse Recorded Resolution(記録された解決の再利用)」を有効化するだけで、Gitが過去のコンフリクト解消手順を自動学習し、二度と同じ衝突で手を動かす必要がなくなります。お楽しみに!

コメント

このブログの人気の投稿

【Perfume】Perfume 3rd Tour 「JPN」さいたまスーパーアリーナに行って参りました~

Perfume 3rd Tour 「JPN」1月28日、29日の2daysで参戦して参りました。 ファンクラブ会員の選考抽選会に28日、29日の両日で申し込んでいたんですが、両方とも当選していたという嬉しい誤算。 仕事だぁ、なんだかんだと紆余曲折ありまして28日の参戦は危ぶまれていたのですが、なんとかかんとか28日は40分遅刻しながらも参戦、29日はフル参戦する事が出来ました(∩´∀`)∩

Perfume、2025年末で“コールドスリープ(活動休止)”へ──東京ドーム2daysの記録と、公式・各界・ファンの声

  1) 公式発表・基本情報 活動休止(コールドスリープ)を正式発表 2025年9月21日、公式サイト「 Perfumeより 」で、2026年から一度コールドスリープに入ると発表。再始動の意思(“新しいPerfume”として戻る)も明記。 Perfume Official Site 今後の運用告知(配信・上映など) 同21日付の「 今後のPerfumeに関して 」で、9/23(火・祝)東京ドーム公演の LIVESHIP全世界生配信 および 全国ディレイビューイング 決定を案内。特設サイトも併記。 Perfume Official Site +1 公式グッズ **「Perfume Calendar 2026」**発売決定(B2壁掛け/表紙+2カ月1枚×6枚+ポスター)。テーマは“フルーツ”。 Perfume Official Site 2) 東京ドーム2days(9/22・23)要点 公演タイトル: ZO/Z5 Anniversary “ネビュラロマンス” Episode TOKYO DOME 。日程・開場/開演・会場・物販等の実務情報は特設で公開。 Perfume Official Site 9/23公演を世界配信(LIVESHIP) /ディレイビューイング実施。 Perfume Official Site 海外向け報道(英語)も「 indefinite hiatus 」として広く配信。 The Times of India 国内英字メディアも速報。 朝日新聞 3) 現地レポ( メリ爺 )から見える空気 あなたの現地記録(9/24公開)を、ファクトと現場情景の両面で反映: 両日参戦 。22日は アリーナ 、23日は 1階席から俯瞰 。前日の発表を受け、開演前のザワつき→MC後に“いつもの一体感”へ。開演は22日 18:45 頃。オープニングは**P³ツアー東京ドーム(2020/2)**と同趣向で“回収”の演出。 メリ爺のゲーム万歳 MC所感 :解散ではなく前向きな休止で不安を和らげる内容。 かしゆか の涙、 のっち の気丈さ、 あ〜ちゃん の思い出語り──3人の結束と「 また戻る 」約束が強く刻まれた。 メリ爺のゲーム万歳 体感時間 : “3時間弱”級のボリューム ながら“過去一...

ニンテンドースイッチでオンラインゲームを遊ぶには?

モンスターハンターライズが発売になって、家族でモンハン楽しみたい人が増えたみたいですね。 某ブログの検索キーワードを調べると、モンハンを家族でやるにはどうしたらいいのか?を調べている人が沢山いるのがわかります。 ※これでも一部  家族で協力するにはSwitch2台、ソフトも2つ購入する必要があります。 1台のスイッチでは遊べませんし、ソフト1つでも遊べません。 でも、1台のスイッチで別々アカウントがあれば交代で遊ぶこともできますよ。セーブデータもしっかり分かれます。 Switchのオンラインゲームを家族で遊ぶ方法については以下の記事にまとめてますのでよろしければ参考にしてみてくださいね。 家族でモンスターハンターライズDL版のオンラインプレーを楽しむ方法