コードを読む前に実行するGitコマンド
(piechowski.io)- 新しいコードベースに触れる際、Git履歴の分析でプロジェクトの構造とリスク領域を把握し、効率的な探索方針を立てる
- 直近1年間で最も頻繁に変更されたファイルを見つけ、変更頻度とバグ集中度を照合して高リスクなコードを特定
- コントリビューターの分布と活動傾向を通じて、バスファクター、保守の空白、知識の断絶の可能性を点検
- 月別コミット数でチームの開発速度と勢いの変化を追跡し、Revert・Hotfixの頻度でリリースの安定性を評価
- この5つのコマンドは、コードを1行も開く前にプロジェクトの健全性を素早く診断する実用的なツールとして活用できる
コードを読む前に実行する5つのGitコマンド
- 新しいコードベースを分析するとき、ファイルを開く前にGit履歴でプロジェクトの健全性を診断するアプローチ
- コミット履歴を通じて、誰が作ったのか、問題がどこに集中しているのか、チームがどれだけ安定してリリースしているのかを把握する
-
何が最も頻繁に変更されているか
- コマンド:
git log --format=format: --name-only --since="1 year ago" | sort | uniq -c | sort -nr | head -20 - 直近1年間で最も多く修正された上位20件のファイルを表示
- 上位のファイルはしばしばチームが「触るのを恐れる」ファイルであり、高い変更頻度(churn) と 所有回避が結びつくと、コードベース最大の負担要因になる
- Microsoft Research(2005) の研究によれば、変更頻度ベースの指標は複雑度指標よりも欠陥予測力が高い
- 上位5件のファイルをバグ集中度のコマンドと照合し、変更が多くバグも多いファイルを最大のリスク要因として特定する
- コマンド:
-
誰がこのコードを作ったのか
- コマンド:
git shortlog -sn --no-merges - コミット数を基準にコントリビューターを順位付けする
- 1人が60%以上を占めていれば、バスファクター(bus factor) のリスクがある
- 上位コントリビューターが直近6か月以内に活動していなければ、保守の空白の可能性がある
- 30人のコントリビューターのうち、直近1年間で3人しか活動していないなら、開発者の入れ替わりによる知識の断絶が起きている
- ただし、squash-merge 戦略を使うチームでは、作成者情報がマージ担当者中心に歪むことがあるため、マージ戦略の確認が必要
- コマンド:
-
バグはどこに集中しているか
- コマンド:
git log -i -E --grep="fix|bug|broken" --name-only --format='' | sort | uniq -c | sort -nr | head -20 - バグ関連キーワードを含むコミットをもとに、バグ発生ファイル上位20件を抽出
- この一覧を変更頻度の一覧と比較し、よく修正され、よく壊れるファイルを高リスクなコードとして特定する
- コミットメッセージの品質によって結果の精度は変わるが、おおまかなバグ密度マップとしても十分に有用
- コマンド:
-
プロジェクトは加速しているのか、停滞しているのか
- コマンド:
git log --format='%ad' --date=format:'%Y-%m' | sort | uniq -c - 月別コミット数を通じて活動の傾向を視覚的に把握する
- 一定のリズムは健全なプロジェクトを意味する
- 1か月でコミット数が半減したなら、中核人材の離脱の可能性がある
- 6〜12か月にわたる継続的な減少はチームの勢いの低下を、周期的な急増と停滞はバッチ型リリースパターンを示唆する
- 実例として、コミット速度のチャートを見て CTO が「あの時点がシニアエンジニアが去った時だった」と認識したケースがある
- このデータはコードのデータではなくチームのデータとして意味を持つ
- コマンド:
-
チームはどれくらい頻繁に緊急対応しているのか
- コマンド:
git log --oneline --since="1 year ago" | grep -iE 'revert|hotfix|emergency|rollback' - Revert・Hotfix の頻度を測定する
- 1年に数件なら正常だが、2週間ごとに発生しているならリリースプロセスへの不信のサイン
- これはテストの不安定さ、ステージング環境の欠如、複雑なロールバック手順など、より深い問題の兆候である
- 結果が0なら、チームが安定しているか、コミットメッセージが不正確な場合
- 危機のパターンははっきり現れ、その有無だけでも信頼性を判断できる
- コマンド:
結論
- この5つのコマンドは数分で実行でき、コードを1行も開く前にどこから読むべきかの方向性を示してくれる
- これによって初日をやみくもに探索するのではなく、問題領域を中心にした体系的なコード分析が可能になる
- この手順はコードベース監査(codebase audit) の最初の1時間にあたり、その後の1週間にわたる分析プロセスへとつながる
1件のコメント
Hacker Newsの意見
Jujutsuでgitの分析コマンドを置き換えられる例が共有されている
過去1年間で最も変更されたファイル、主要な貢献者、バグが集中している場所、プロジェクトの活力、緊急修正の頻度などを
jj logコマンドで確認できるシェルスクリプトよりもプログラミングに近い文法だが、覚えるべきフラグの数は少ない
Nixが魅力的だが複雑さを増すように、jujutsuにも同じ印象を受けた
数か月使ってみたがgitに戻った。gitは手になじんでいて、どこでも使えるからだ
jqで配列のループを覚えているだけでも十分なのに、こういう文法はまったく感覚がつかめない
よく使うならaliasで短縮して使う
たとえば10年間更新のないQRコード生成ライブラリがあるが、完全に動作している
わざわざボットで役に立たないコミットを追加すべきか悩むことがある
だからjujutsuのようなツールより、従来のUNIXパイプコマンドを好む
GradleではなくMavenを使う理由も同じ文脈だ
筆者が開発者はコミットメッセージをきちんと書くと仮定していたのが面白かった
現実には大半が「changed stuff」レベルだ
私のようにコミットログを重視する人は少数派だ
AIが生成するコミットメッセージはこの問題を大いに助けられる
開発者は自由にコミットメッセージを書いてよく、どうせ後では読まれない
CoreではPRレビューと詳細な説明が必須で、Non-Coreでは自由に実験できる
Coreではコミットメッセージがコードの20倍長いこともあるが、Non-Coreでは「hope this works」レベルだ
私たちの会社ではそれを互いに求めている
複数のコードベースでコマンドを回してみたが、結果は実情と異なっていた
たとえば
git shortlog -sn --no-mergesの結果で、最もコミット数が多い人がすでに退職していることもあったコミット数が多いからといって貢献度が高いとは限らない
必要以上に多いコミットはfeatureブランチにだけ残し、メインにはきれいにマージする
普通のコードベースでは意味の薄い結果しか出ない
プロジェクトを最初から作ったからで、今では他の人たちのほうが頻繁にコミットしている
「最も多く変更されたファイルが、人々が触るのを恐れているファイルだ」という話は興味深かった
単に実行結果だけで結論を出すと、かえって浅はかに見えることがある
実際には過去1年間にどの機能に取り組んでいたかを示す程度だ
どちらも高い場所こそ本当の問題領域だ
こうした領域が積み重なると、「アプリを最初から書き直すべきだ」という話になる
誰もが修正しなければならないが、大きすぎて扱いづらい
私はgitにsummary aliasを作っていて、ブランチ要約、コミット数、作成者数、ファイル数などを一度に出力する
GitAlias/gitalias から着想を得た
.gitconfig関数で書いたのか気になる。普通にgit-summaryスクリプトにしたほうが簡単に見えるlog-of-count-and-emailのようなコマンドはない正規表現に**単語境界(\b)**を追加すべきだ
たとえば「debugger」に含まれる「bug」のせいで誤った結果になる可能性がある
修正例は次のとおり
git log -i -E --grep="\b(fix|fixed|fixes|bug|broken)\b" ...\bをサポートしないため、-Eの代わりに**Perl正規表現オプション-P**を使う必要があるgit log -i -P --grep="\b(...)\b"の形に修正できるsquash-mergeをしないと、コミット数が多い人ほどむしろ最もひどい開発者かもしれない
昔そういう人がいて、同じファイルばかり何度も修正した末に結局解雇された
squashはこうした問題を隠してくれる良い方法だ
単純なコミット数の統計は信頼しづらい
完璧にテストされたコードだけをコミットする人もいれば、1行ずつ頻繁にコミットする人もいる
1つのコミットの価値は人によって100倍違う
絶対値より変化率のほうが意味がある
こうした分析アプローチは**Adam Tornhillの『Your Code as a Crime Scene』**を思い出させる
原文リンク
また、Developer’s Legacy Index という概念にも似ている
筆者が各コマンドの結果を直接見せてくれていたら、もっと良かったと思う
説明よりも出力例のほうが説得力があったはずだ