ボーイスカウトルールは、Robert C. Martin(Uncle Bob)が2010年のエッセイで示した「モジュールはチェックアウトした時よりも綺麗にしてチェックインする」という開発上の規則です。定義そのものは一文で終わります。つまずくのはその先で、善意の小改善はレビュー差分を膨らませ、git blame が示す更新元を書き換えてしまいます。この記事では原文の逐語、同じコミットに入れてよい変更の線引き、差分を汚さないGitの手順、そしてCIの合否条件に変える方法までを扱います。なお、青少年団体としてのボーイスカウトの「おきて」を探して来られた場合、本記事はソフトウェア開発の話題です。
まとめ
先に結論を挙げます。
- 原文の規則は「Always check a module in cleaner than when you checked it out.」で、綺麗にする対象は自分が触ったモジュールに限られます。リポジトリ全体の清掃を求めるものではありません。
- エッセイが挙げる改善は、変数名の改善・長い関数の分割・循環依存の解消・インターフェース抽出です。原文が求めるのは既存の何か1つ以上で、上限は定めていません。本記事ではレビューしやすくするため、振る舞いを変える変更と構造改善を別コミットにする運用を勧めます。
- 整形や改名だけのコミットは機能変更と分け、そのコミットハッシュを
.git-blame-ignore-revsに記録します。Git 2.23.0以降のgit blame --ignore-revs-fileで追跡性を維持できます(本記事で実行確認済み)。 - 個人の心がけに任せると続きません。SonarQubeの「Clean as You Code」は同じ考え方を変更行だけを対象にした品質ゲートとして自動化します。
- テストの無い領域とリリース直前のブランチでは適用しません。別チームが所有するファイルは、担当チームの合意を取ってから触ります。
ボーイスカウトルールの定義と出典
原文の適用範囲と改善の最低条件
出典は O’Reilly の書籍『97 Things Every Programmer Should Know』(Kevlin Henney編、2010年)に Uncle Bob が寄稿したエッセイ「The Boy Scout Rule」です。原文はキャンプ場の規則を引いたうえで、コードへの適用をこう書いています。
「What if we followed a similar rule in our code: “Always check a module in cleaner than when you checked it out.”」
ここで重要なのは適用範囲です。原文は続けて「You don’t have to make every module perfect before you check it in. You simply have to make it a little bit better than when you checked it out.」と書いており、完璧さも網羅性も求めていません。要求は2点だけで、追加するコードは綺麗であること、そしてチェックインする前に既存の何か1つを綺麗にすること(「you clean up at least one other thing before you check the module back in」)です。触っていないファイルまで清掃して回る運用は、原文の求める範囲を超えています。
エッセイの締めくくりは、コードを汚したまま放置する行為をポイ捨て(littering)と同列に置き、個人ではなくチームがシステム全体を世話する状態を目標に据えています。つまりこの規則の狙いは、コードの美しさそのものではなく、日々の改善によってコードの劣化を抑え、チーム全体でシステムを手入れすることにあります。同じ著者の『Clean Code』(Prentice Hall、2008年)第1章にも「The Boy Scout Rule」節があり、「If we all checked-in our code a little cleaner than when we checked it out, the code simply could not rot.」と、コードの腐敗を止める手段として位置づけています。
この「腐敗させない」という発想の下敷きにあるのが、Ward Cunninghamが1992年のOOPSLAで示した技術的負債のたとえです。原稿は「Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite.」と述べ、危険なのは借りることではなく返さないことだと続けています。ボーイスカウトルールは、この返済を一度に行う代わりに、コードを触るたびの最小単位へ分割する運用だと理解すると位置づけがはっきりします。
「来た時よりも美しく」の出典とキャンプ場への翻案
日本語の解説では「来た時よりも美しく」がボーイスカウトの規律として紹介されがちですが、エッセイ自身がその点を注記しています。
「Actually the original form of that rule, written by Robert Stephenson Smyth Baden-Powell, the father of scouting, was “Try and leave this world a little better than you found it.”」
Baden-Powell のこの一節は、1941年1月8日の死後に遺品から見つかった「Last message to Scouts」に含まれるもので、対象はキャンプ場ではなく世界です。『Clean Code』も同じ箇所に脚注を付け、「This was adapted from Robert Stephenson Smyth Baden-Powell’s farewell message to the Scouts」と、翻案であることを明示しています。「Always leave the campground cleaner than you found it.」はキャンプ場に置き換えた通俗版であり、スカウト運動の公式な掟の条文ではありません。記事や社内資料で由来を書くときは、この2段階の言い換えを踏まえておくと出典の誤りを避けられます。
ボーイスカウトルールの日本語表記と呼称
検索では「ボーイスカウトルール」「ボーイスカウト・ルール」「ボーイスカウトの原則」「boy scout rule」が並立していますが、いずれも同じ Uncle Bob のエッセイを指します。日本語版『プログラマが知るべき97のこと』の章題は中黒入りの「ボーイスカウト・ルール」で、中黒を省いた表記と、Rule を「原則」と言い換えた表記が後から広まりました。本記事ではこれらを同じ考え方の表記として扱います。
プログラミングでの適用範囲
エッセイとClean Codeが挙げる改善の中身
エッセイは具体例を4つだけ挙げています。「You might simply improve the name of one variable, or split one long function into two smaller functions. You might break a circular dependency, or add an interface to decouple policy from detail.」です。『Clean Code』側の列挙はやや異なり、「Change one variable name for the better, break up one function that’s a little too large, eliminate one small bit of duplication, clean up one composite if statement.」となっています。2つの出典に共通するのは、外から観測できる振る舞いが変わらない改善だけを挙げている点です。
一方、日本語の解説記事でよく足される「軽微なバグ修正」「不要なコードの削除」「テストの追加」は、どちらの出典にも含まれていません。バグ修正は振る舞いを変えるため機能変更として扱うべきで、未使用コードの削除はリフレクションや動的呼び出しがある言語では振る舞いを変え得ます。テストの追加は原文の列挙にはありませんが、列挙は改善の例示であり、テスト追加を実施記録から除外する規定はありません。『Clean Code』が挙げる重複の除去については、判断の目安をコードの重複とは何か? 定義と発生する典型的なケースを具体例と共に詳しく解説し、重複コード問題を理解するで整理しています。
| 変更の種類 | 小改善コミットの扱い | 判断の根拠 |
|---|---|---|
| 変数名・関数名の改善 | まとめてよい | 原文が明示。IDEの改名機能で機械的に完結 |
| 長い関数の分割 | まとめてよい | 原文が明示。振る舞いは不変 |
| 小さな重複の除去 | まとめてよい | Clean Codeが明示。範囲がモジュール内で閉じる |
| 複合if文の整理 | まとめてよい | Clean Codeが明示。条件式の等価変換 |
| 循環依存の解消 | 分けて出す | 影響範囲がモジュール外へ及ぶ |
| インターフェース抽出 | 分けて出す | 依存関係や利用側への影響を確認 |
| フォーマッタの一括適用 | 分けて出す | blame汚染の主因 |
| 未使用コードの削除 | 分けて出す | 動的参照で振る舞いが変わり得る |
| バグ修正 | 分けて出す | 振る舞いの変更。単独で追跡・切り戻しが必要 |
構造改善の着手判断と切り戻し単位
改善できる箇所を見つけても、着手しない方がよい場面があります。判断の軸は「その変更が壊れたとき、単独で切り戻せるか」です。機能変更のコミットに改名が同居していると、revert は改名まで巻き戻してしまいます。改名だけのコミットであっても、参照先の更新漏れや公開APIへの影響は差分とテストで確認してから承認してください。手続きとしての線引きは、章末のGit運用で具体化します。
どこまでを構造改善と呼ぶかの体系はリファクタリングとは?24の観点とタイミング・進め方で観点別に整理しています。ボーイスカウトルールはそのうち「いつやるか」を日常の作業単位に落とした運用ルールにあたります。
差分を汚さずに適用するGitの手順
整形・改名と機能変更のコミット分離
作業中に改善点に気づいたら、その場で直してから git add -p でハンク単位に選び、コミットを分けます。メッセージの接頭辞を分けておくと、レビュー担当者が読む順序を決められます。
git add -p
git commit -m "refactor: rename tmp to elapsedMs"
git add -p
git commit -m "fix: guard against null session"
コミットの粒度と規約の決め方はGit運用のベストプラクティス|ブランチ戦略・コミット規約・レビュー基準の決め方で扱っています。ボーイスカウトルールを導入するなら、規約側に「構造変更と振る舞い変更を同じコミットに入れない」の一行を足すのが最短です。
.git-blame-ignore-revs による整形コミットの除外
小改善がレビューで嫌われる理由の一つが git blame の汚染です。整形コミットが挟まると、行の由来がすべて整形コミットに書き換わり、なぜその行があるのかを追えなくなります。Git 2.23.0(2019年8月)で git blame に無視機能が入り、この問題は運用で回避できるようになりました。リリースノートの記述は「“git blame” learned to “ignore” commits in the history, whose effects (as well as their presence) get ignored.」です。
使い方は、無視したいコミットのハッシュを1行1件で記録し、設定に登録するだけです。
# HEADが整形だけのコミットであることを確認してから記録する
git log -1 --format=%H >> .git-blame-ignore-revs
# このローカルリポジトリの既定として登録する
git config blame.ignoreRevsFile .git-blame-ignore-revs
# 以降 git blame は整形コミットを飛ばして表示する
git blame app.ts
実際の挙動を確認しておきます。初期コミット・整形のみのコミット・値を変更したコミットの3つを積んだリポジトリで git blame を実行すると、1行目の由来は整形コミット e9c517df になります。整形コミットを .git-blame-ignore-revs に登録して再実行すると、同じ行の由来は初期コミット 4da8706 に戻り、値を変えた2行目は元のコミットのまま残ります(Git 2.50.1で実行、2026年9月11日確認)。
# 登録前
e9c517df (t 2026-09-11 1) const a = 1;
a906c74a (t 2026-09-11 2) const b = 3;
# 登録後
^4da8706 (t 2026-09-11 1) const a = 1;
a906c74a (t 2026-09-11 2) const b = 3;
公式ドキュメントは blame.ignoreRevsFile について「Ignore revisions listed in the file, one unabbreviated object name per line」と定めており、短縮ハッシュは受け付けません。%H(フル)で記録してください。%h の短縮ハッシュを書いたファイルを渡すと、手元のGit 2.50.1では fatal: invalid object name: c1b65e8 で停止します。ファイル名 .git-blame-ignore-revs 自体は Git の仕様ではなく慣例ですが、GitHubはこの名前を特別扱いします。GitHub公式ドキュメントは「All revisions specified in the .git-blame-ignore-revs file, which must be in the root directory of your repository, are hidden from the blame view」と記載しており、リポジトリ直下に置けばWeb上のblameビューにも自動で反映されます。
コミット済みの変更ファイルに限定した整形
リポジトリ全体にフォーマッタをかけると、それ自体が巨大な整形コミットになります。触ったファイルだけに絞れば、ボーイスカウトルールの適用範囲と一致します。
# コミット済みの差分から、追加・コピー・変更・改名されたファイルを取る
git diff --name-only -z --diff-filter=ACMR origin/main...HEAD -- '*.ts' \
| xargs -0 npx eslint --fix --fix-type layout --
--diff-filter=ACMR は追加・コピー・変更・改名されたファイルを選ぶ指定で、これを省くと削除済みのパスが xargs に渡って失敗します。-z と xargs -0 はセットで必要です(省くと has space.ts のような空白入りのパスが2引数に割れます。手元のGit 2.50.1で確認)。--fix-type layout は ESLint公式が「apply fixes that do not change the program structure (AST)」と定める区分で、自動修正を構文木を変えない範囲に閉じ込められます。コミット前に自動で走らせるなら lint-staged 等のpre-commitフックに同じ考え方を移します。ツール選定はコード品質管理における自動化ツールの活用方法が参考になります。
Clean as You CodeとNew Codeの品質ゲート
ボーイスカウトルールは個人の規律として語られてきたため、実施率が測れず、忙しくなると最初に落ちます。これを計測可能にしたのがSonarの「Clean as You Code」です。公式ドキュメントは開発者の立ち位置を「As a developer, you focus on maintaining high standards for the code you add or change.」と書き、さらに「By focusing on new code, you aren’t responsible for anyone else’s code.」と、他人のコードまで背負わせない点を明示しています。追加・変更したコードだけを対象にするという線引きは、エッセイの「触ったモジュールを少し良くする」と同じです。現行のドキュメントではページ名が「Quality standards and new code」に変わっており、Clean as You Code の呼称は製品UIと専用プラグイン(Clean as You Code stats)に残っています。
実装上の鍵は「New Code」の定義です。SonarQubeは「New code is code that you’ve recently added or modified.」とし、プルリクエスト解析では「new code is defined as the code that has changed in the pull request branch compared to the target branch. Only issues on new code are reported.」と明記しています。既存コードの指摘は合否に影響せず、そのPRで触った範囲だけがゲートの対象になります。組み込みのSonar way品質ゲートも、条件をNew Codeにのみ適用します。
New Codeの区切り方は Previous version、Number of days、Specific analysis、Reference branch の4種類で、グローバルの既定は Previous version です(「The default baseline for new code is the Previous version option.」)。Number of days を選んだ場合の既定値は30日で、上限は90日と定められています。バージョンを切って出荷する製品なら既定の Previous version のまま、継続的デリバリーで版番号を打たないなら Reference branch へ変えるのが素直な対応です。
品質ゲートは設定した条件の合否を自動判定しますが、改善内容の妥当性や設計意図、振る舞いの維持はレビューとテストで確認します。製品としての機能範囲や料金はSonarQube(ソナーキューブ)とは?できること・対応言語・料金とSonarLintとの違いをわかりやすく解説にまとめています。
ボーイスカウトルールを適用すべきでない場面
この規則には明確な失敗パターンがあります。等しく推奨できるものではないので、以下の条件に当たるなら適用を止める判断が正しいと考えます。
テストが無い領域では適用しません。関数分割も改名も、振る舞いが変わっていないことを機械的に確認できて初めて安全です。テストが無いなら、まず特性化テストを書く作業が先行し、それは「ついでの小改善」の枠に収まりません。テストの有効性そのものを疑うならミューテーションテストとは?ミュータント生成とスコアの読み方を実装者向けに解説の指標が判断材料になります。
リリース直前のブランチでは適用しません。差分が小さいほど回帰リスクの評価が容易になるため、凍結期間中の構造変更は費用対効果が逆転します。
別チームが所有するファイルは、担当チームと合意せずに変更しません。レビュー権限を持つチームに無断の改名を送りつけると、レビュー待ちでPRが滞留し、結果として自分の機能変更まで止まります。
裏返せば、テストがあり、リリースまで余裕があり、自チームが所有するファイルなら、小改善は後回しにせずその場で片付ける方が費用対効果は高くなります。Martin Fowlerは「Is High Quality Software Worth the Cost?」(2019年5月29日)で「Developers find poor quality code significantly slows them down within a few weeks.」と述べており、内部品質の劣化が開発速度に効き始めるのは数年後ではなく数週間後だという立場を取っています。同記事の結論は「The “cost” of high internal quality software is negative.」で、続けて「The usual trade-off between cost and quality (中略) does not make sense with the internal quality of software.」と書いています。コストと品質のトレードオフが崩れるのは内部品質に限った話です。ユーザー体験のような外部品質については、同記事も従来どおり成立するとしました。
定量的な裏付けとしては、Adam TornhillとMarkus Borgの「Code Red: The Business Impact of Code Quality」(arXiv:2203.04374、2022年3月8日投稿)があります。39の商用コードベース・30,737ファイルを分析し、低品質なコードは高品質なコードの15倍の欠陥を含み、課題の解決には平均124%多くの時間がかかり、最大サイクルタイムは9倍に達したと報告しています。なお同論文の要旨にある「技術的負債が開発者の時間を最大42%浪費する」は先行研究の推計であり、この39コードベースの実測値ではありません。
また、目的が「次の機能追加を楽にすること」に定まっているなら、Fowlerが Preparatory Refactoring と呼ぶ進め方が近道です。同氏は Kent Beck の「for each desired change, make the change easy (warning: this may be hard), then make the easy change」を引き、機能追加の直前に必要な構造だけを整える手順を推奨しました。手当たり次第の清掃より、目的から逆算した構造変更の方が投資として説明しやすくなります。
よくある質問
ボーイスカウトルールとボーイスカウトの原則は違うものですか?
同じものです。どちらも Uncle Bob が『97 Things Every Programmer Should Know』に寄稿したエッセイ「The Boy Scout Rule」を指します。日本語では「ボーイスカウト・ルール」「ボーイスカウトの原則」の両方が使われますが、定義に差はありません。
「来た時よりも美しく」はボーイスカウトの掟に書かれているのですか?
掟の条文ではありません。エッセイ自身が、原型は創始者 Baden-Powell の「Try and leave this world a little better than you found it.」だと注記しています。キャンプ場に置き換えた「Always leave the campground cleaner than you found it.」は通俗的な言い換えです。
リファクタリングとボーイスカウトルールはどう違いますか?
リファクタリングは振る舞いを変えずに内部構造を改善する手法そのものを指し、ボーイスカウトルールはそれをいつ・どの範囲で行うかを定めた運用規則です。Martinの原文は、チェックアウトしたモジュールで既存の何かを少なくとも1つ改善するよう求めており、改善箇所の上限は定めていません。
レビュー担当者に「差分が読みにくい」と言われたらどうすればよいですか?
構造変更と振る舞い変更が同じコミットに入っている可能性が高いので、git add -p でコミットを分けてください。レビュー差分はコミット分離で整理します。別途、整形コミットの完全なハッシュを .git-blame-ignore-revs に追記し、ローカルのGitにも設定すれば、以降のblameから除外できます。レビュー観点の整理はコードレビューとは?目的・観点・進め方と実装現場の運用設計を解説を参照してください。
チーム全員に守らせるにはどうすればよいですか?
心がけとして掲示しても実施率は測れません。SonarQubeのようにNew Code(そのPRで変更した範囲)だけを対象にする品質ゲートをCIに組み込み、落ちたらマージできない状態にするのが確実です。PR解析ではターゲットブランチとの差分が対象です。ブランチ解析でNumber of daysを選んだ場合の日数は既定30日、上限90日です。