開発の足回りi-Willink
少人数の開発で、戻せる状態を残すブランチの使い方
少人数でも、本番に出すブランチを直接いじると、失敗したとき戻す手段を自分で捨てることになります。短い作業用ブランチ、機械の検査、戻せない操作の封印。90日で1,689件の変更を回した私たちの決まりを書きます。
少人数の開発で守るべきは「後で戻せること」です。本番に出す main は直接いじらず、短い作業用ブランチで変え、機械の検査を通してから戻します。履歴を消す操作は日常の手順から外します。
レビューしてくれる同僚がいない少人数の開発では、手順はなるべく軽くしたくなります。けれども、本番に出すブランチを直接いじると、事故が起きたときに戻す手段を自分から捨てることになります。
私たちの開発は、社長とAIの2者でほぼすべてを回しています。この記事では、その速さに合わせて決めたブランチの使い方を、社内の開発標準と実際の数字から紹介します。
この記事の要点
- 1長く残すブランチは main だけ。作業は数時間で main に戻る短いブランチで行う
- 2人のレビューは入れられない速さなので、代わりに機械の検査を必須にする
- 3「マージした」と「本番に出た」は別。本番の画面を確かめるまで完了と言わない
- 4履歴を消す操作(reset --hard・force push)は日常の手順から外し、機械で止める
少人数の開発は、思ったより速い
制定のために測ると、5つのリポジトリで90日に1,689件の変更が取り込まれていました。1日あたり約19件です。この速さには、人の目によるレビューは入りません。
| 測ったもの(5リポジトリ・90日) | 値 |
|---|---|
| 取り込まれた変更(PR) | 1,689件(1日あたり18.8件) |
| 1件あたりのコミット数(中央値) | 1 |
| 作業用ブランチの寿命(中央値) | 0.01〜0.91時間 |
| GitHub 上の人のレビュー | ほぼ0件(外部からの1件のみ) |
AIと開発すると、変更の数は人だけのときよりずっと増えます。そこに「毎回人が目を通す」手順を置くと、人が詰まり、全体が止まります。そこで私たちは、人の目の代わりに機械の検査を必須にし、人の判断は取り消せない地点だけに置くことにしました。
長く残すのは main だけ
main は常に本番に出せる状態に保ち、作業は短い作業用ブランチで行います。作業用ブランチは数時間で main に戻して消します。
私たちのやり方は、trunk-based と呼ばれる形に近いものです。長く残すブランチは main の1本だけで、作業はそこから切った短いブランチで行い、検査が通ったらすぐ main に戻します。作業用ブランチを長く残すと、main との差が開き、戻すときに衝突が増えるからです。
main に入る方法は、変更の種類で分けています。社内の文書や記録だけの変更は直接入れてよく、プロダクトのコード、検査の仕組み、設定の変更は、必ず PR(変更の取り込み依頼)を通して機械の検査を受けます。
一人でも PR を挟む意味はあります。差分の画面で変更を通して見ると、消し忘れたデバッグ用のコードや、混ざり込んだ関係のないファイルに気づけます。PR は、作業を一度立ち止まって見直す場所でもあります。
「マージした」と「本番に出た」は別
main に取り込んでも、本番に反映される工程が別にあるなら、まだ公開されていません。本番の画面を確かめるまで「完了」と言わない決まりにしています。
私たちのサイトは、main に取り込んだだけでは本番に出ません。別の配置の工程が走って、はじめて公開されます。この前提を忘れて「マージしたから直った」と思い込み、実際には本番が古いまま、という失敗を私たち自身がしました。
それ以来、本番に関わる変更は、配置の工程が成功したことと、本番の画面が新しくなったことの2つを確かめてから完了としています。
戻せない操作を、日常の手順から外す
作業中の変更を一気に捨てる git reset --hard と、共有の履歴を上書きする force push は使いません。取り消しは、履歴を残す方法に寄せます。
| したいこと | 使わない操作 | 代わりに使う操作 |
|---|---|---|
| 作業中の変更を一度どける | git reset --hard(変更を捨てる) | git stash(退避して後で戻せる) |
| 公開済みの変更を取り消す | 履歴の書き換え | git revert(打ち消す変更を新しく積む) |
| ブランチの履歴を整える | git push --force(共有の履歴を上書き) | 新しいブランチを切り直す |
reset --hard は速いですが、捨てた瞬間に選択肢がゼロになります。force push は、CI や配置の仕組みが参照していた履歴を消します。少人数だと「さっき自分が何をしたか覚えている」前提で作業しがちですが、その記憶がいちばん当てになりません。
私たちはこの2つを、決まりとして書くだけでなく、AIが実行しようとしたときに機械で止める仕組みにしています。決まりは忘れられますが、止める仕組みは忘れません。
少人数のための最小の決まり
短いブランチ、機械の検査、本番の確認、戻せない操作の封印。この4つを崩さないことだけを優先しています。
作業用ブランチと PR という形は、私たちが考え出したものではありません。Martin Fowler の解説や GitHub Flow の説明にあるように、ウェブの開発では広く使われている基本形です。私たちがしているのは、それを少人数とAIの速さに合わせて、余計な手順を削って運用していることだけです。
まずは「main を直接いじらない」の1行だけ決めてみてください。それだけでも、事故が起きたときの逃げ道が残ります。
よくある質問
一人で開発していても、PR を作る意味はありますか?
あります。差分を通して見直す場所になりますし、機械の検査を必ず通す入り口にもなります。私たちは人のレビューを入れない代わりに、PR で機械の検査を必須にしています。
git reset --hard は使ってはいけないのですか?
捨てた変更は戻せないので、日常の手順からは外しています。作業中の変更をどけたいなら git stash、公開済みの変更を取り消したいなら git revert を使うと、後から戻せます。
マージしたのに本番が変わらないのはなぜですか?
多くの場合、本番に反映する工程が別にあるからです。配置の工程が成功したかと、本番の画面が新しくなったかを確かめてください。
参考・出典
- Feature Branch(Martin Fowler)(作業用ブランチの考え方と、長く残すことの問題)
- GitHub flow(GitHub Docs)(ブランチ・PR・マージの基本の流れ)