トランクベース開発とは?小さく毎日マージする方法
要約
トランクベース開発とは、チーム全員が共有の main(trunk)へ小さな変更を1日1回以上マージする開発手法です。長命ブランチを避け、未完成の機能はフィーチャーフラグで隠します。DORA の研究では、この習慣が配信の速さと安定性に結び付いています。まずは1つの小さな変更を今日マージしてみてください。
トランクベース開発とは、チーム全員が1本の共有ブランチ(通常は main または trunk と呼ばれるもの)へ、小さな変更を少なくとも1日に1回マージしていく開発手法です。ブランチを使う場合も、寿命は数週間ではなく数時間です。完成していない作業はフィーチャーフラグの裏に隠して出荷するので、どのコミットでもトランクはリリースできる状態に保たれます。仕組みの中身はそれだけで、名前から想像するほど大げさではありません。
ここで、ひとつの場面を思い浮かべてください。3週間放置していたサイドプロジェクトを開きます。フィーチャーブランチは main より41コミット遅れていて、2つのファイルで衝突し、作っていた機能は周りのコードと噛み合わなくなっています。トランクベース開発は、この場面を起こさないための習慣です。
トランクベース開発が実際に意味すること
trunkbaseddevelopment.com の解説サイト は、開発者が1本の共有ブランチで協業し、長く残る開発ブランチを避けるソース管理モデルとして定義しています。とても小さなチームなら、トランクへの直接コミットも問題ありません。プルリクエストを使うのも構いませんが、フィーチャーブランチは短命で、1人の作業から生まれたものに限られている必要があります。
大事なルールは3つです。
1日に1回以上はトランクへマージする。
トランクを緑(ビルド成功)に保つ。main が壊れたら、それが全員の最優先事項になる。
未完成の作業はサイドブランチに置かず、フィーチャーフラグで隠す。
逆に、何が無いかに注目してください。develop ブランチもなく、機能ごとの長いリリースブランチもなく、最後に全員がコードの噛み合わなさに気づく統合フェーズもありません。古いモデルで痛い目を見るのは、痛みを溜め込んでから一度にまとめて払うことになるからです。

長命ブランチは借金だから、小さなチームほど避けたい
長命ブランチは借金のようなものです。ブランチが生きている1日ごとに、main から少しずつ離れていきます。その利子は、マージコンフリクト、古くなった前提、そして60ファイルに触れる差分のせいで終わらないレビューという形で返ってきます。
DORA の trunk-based development 解説ページ は、この習慣を、State of DevOps の調査に基づいて、配信の速さ・安定性・可用性の向上と結び付けています。リポジトリのアクティブなブランチは3本以下にする。1日に1回以上トランクへマージする。コードフリーズと統合フェーズを避ける。どれも測定できる具体的な目標で、この分野では珍しいことです。
ソロ開発者や3人のチームなら、理屈はさらにシンプルです。小さなマージはレビューしやすく、戻しやすく、半年後に22時の git blame を眺めながら「過去の自分は何を考えていたのか」と悩むときにも理解しやすい。
やる理由は3つ、やらない理由は1つです。やる理由は、差分が小さいこと、CI からの返事が速いこと、金曜日に main をデプロイしても落ち着いていられることです。やらない理由は、テストが薄いと、毎日のマージは壊れ方を速く広げるだけという点です。これは後で扱います。
短命ブランチか、main への直接コミットか
どちらもトランクベース開発に含まれます。違いは、コードが入る前にどれだけの安全策を求めるかです。
1人かペアで作業していて、ローカルのビルドが1分未満で終わり、テストを信頼できるなら、main への直接コミットが最速のループです。多くの個人開発者は、名前を付けていないだけで既にこれをやっています。
2人目、3人目が加わったときや、マージ前にクリーンな環境で CI を回したいときは、プルリクエストと短命ブランチが合っています。規律は「短命」という言葉に詰まっています。翌日まで生き残るブランチは、もう抜け出そうとしているモデルへ向かっています。
続けやすい手順は次のとおりです。
main を pull して、何の変更かが分かる名前でブランチを切る。
前に進める最小の変更を作り、ローカルでビルド全体を回す。
PR を開いて CI を走らせ、同じ日にマージする。
ブランチを削除する。溜め込まない。
1日で終わらない変更なら、答えは長いブランチではありません。変更をもっと薄く切ることです。
完成していない作業を、main を壊さずに出荷するには
ここで多くの人が止まります。毎日マージするなら、まだ存在しない機能のコードも入れることになるからです。対処法は2つあります。
1つ目はフィーチャーフラグです。新しいコードパスはマージするが、スイッチはオフのままにして、ユーザーには見せません。フラグは環境変数の真偽値程度に単純で構いません。
const showNewCheckout = process.env.FEATURE_NEW_CHECKOUT === "true";
export function Checkout() {
return showNewCheckout ? <NewCheckout /> : <OldCheckout />;
}個人開発ならこれで十分です。対象の絞り込み、段階的なロールアウト、再デプロイなしのキルスイッチが必要になったら、マネージドサービスを使う価値が出てきます。
2つ目はブランチ・バイ・アブストラクションです。データベースクライアントや決済プロバイダの差し替えなど、大きな変更向けです。古い実装の前にインターフェースを置き、同じインターフェースの裏で新しい実装を作り、呼び出し元を少しずつ移してから古い実装を削除します。どのステップも、トランクへの小さなマージで、長いブランチに何かが残ることはありません。

フラグには注意点もあります。フラグは負債です。1年間コードに残ったフラグは、偽装されたブランチです。各フラグに担当者と削除日を決め、機能が完全に展開されたら削除してください。
トランクベース開発の前に、CI に必要なこと
安全網のないトランクベース開発は、速く壊れるだけです。毎日マージする習慣を始める前に、次の3つを用意しましょう。
すべての push で走り、数十分ではなく数分で終わるビルド。
本当に壊れたときに失敗するテスト。カバレッジの数字より、悪い変更を捕まえられるかどうかが重要です。
すぐに戻す方法。コミットを revert するか、フラグをオフにする。
静的解析は、安く追加できる防御の層です。明らかなバグ、セキュリティ上の臭い、重複コードなどを、人間が差分を読む前に捕まえてくれます。
レビュアーが自分ひとりなら、リスクの高い箇所を指摘してくれるツールはさらに役立ちます。何度も触っているファイルが少しずつ泥だらけになっていても、他の誰も教えてくれないからです。
初日から重いパイプラインが必要だと考える必要はありません。main をインストール、lint、テスト、デプロイする1つのワークフローファイルで、十分な出発点になります。最初のバージョンは動けば上出来で、最適化は後からできます。
リリースブランチ、ホットフィックス、それでも気をつける場面
トランクベース開発は、リリースブランチを禁じていません。リリース直前にトランクから枝を切り、固めて、出荷し、削除するチームもあります。別のチームはトランクから直接リリースし、バグが見つかったら先へ進む形で直します(fix forward)。週に数回デプロイするウェブアプリなら、先へ直すほうがほぼ常に単純です。
モバイルアプリや、ストア審査に時間がかかるものは事情が違います。すでにユーザーの手元にあるバージョンにパッチを当てるため、バージョンごとに短命のリリースブランチを残すことがあります。それでもルールは同じです。修正は先にトランクへ入れ、その後にチェリーピックします。逆順はありません。
ホットフィックスも同じ論理です。トランクで直して、デプロイして、終わり。トランクに戻されない別のホットフィックスブランチは、2つに分かれた履歴を生む典型的な原因です。

最初の1週間の現実的な進め方
1日目:今のリポジトリのブランチを確認します。開いているブランチを一覧にして、それぞれの経過時間を書き出してください。数日以上前のものは、マージするか削除する候補です。これだけで、摩擦がどこにあるか見えることが多いです。
2日目:フラグの仕組みを追加します。環境変数でも構いません。進行中の機能を1つ選び、その入口をフラグの裏に置いてから、今ある分をマージします。
3日目から5日目:習慣を変えます。作業を1日で入るサイズに切り、CI が通ったら1片ずつマージします。最初の数片は小さすぎると感じるはずですが、そうではありません。休眠中のデータベースカラムや、まだ使われていない関数を追加するコミットでも、安全で、レビュー済みで、すでに統合された立派な進捗です。
週の終わりには、2つのことがわかります。テストをどこまで信頼できるか、そしてどの部分が小さな変更を拒むのか。どちらも、長いブランチで作業しているだけでは見えてきません。
測るためにダッシュボードは要りません。ブランチがどれくらい生きているか、main がどれくらい赤くなるか、最初のコミットから本番までどれくらいかかるか、を見てください。ブランチの寿命が縮み、デプロイが退屈になっていけば、習慣は効いています。
フラグの裏に置いた機能が利用者にどう効くかを知りたいなら、実験ツールでロールアウトを実際の指標に結び付けられます。感覚ではなく数字で判断できます。
1人で開発しているなら、ノートに書き留めるだけでも十分です。1か月間、毎週、最初のコミットから本番までの時間を記録してください。1回の数字より、その傾向のほうが多くを教えてくれます。
乗り換えるべきか、待つべきか
1人、ペア、またはテストを半分信頼できて CI を改善の余地がある小さなチームなら、乗り換えてください。試すコストは、1週間の少し居心地の悪い小さなコミットだけです。長いブランチに居続けるコストは、コンフリクトと遅いレビューで払うことになり、協力者が増えるたびに大きくなります。
自動テストがまったく無く、戻す手段もないなら、待ってください。先にそこを直すべきです。テストのないトランクへ毎日マージしても、痛みが場所を変えるだけです。
完璧な方法ではありません。実用的な方法です。今のプロジェクトで次の小さな変更を1つ選び、今日マージしてみてください。どんな感じがするか、確かめてみましょう。今夜までに出荷できる、現在の機能の一番小さな切り口は何でしょうか。