機能を実装している過程で、ついつい、関連する修正をアレもコレも、まとめて実装して、大きいコミットを作ってしまうことがある。 コミットは特定の作業毎に小さくまとまってる方が、あとから見直すときに、そのコミットでやろうとしていたことが、理解しやすいので助かる。 大きいコミットは見るのが辛いので、小さくするように心がけたいものだ。
けれど、○○な機能を実装している途中で、△△を修正しないとダメだから、先に△△の作業をやるか・・・という状況がよくある。 △△の修正だけを先にコミットしようにも、○○の作業で同じソースコードにすでに修正が入っていて、キレイに△△の修正だけでコミットするのが難しい。 だから、やむなく、○○と△△をまとめて、○○の修正として大きなコミットを作ってしまう。
処方箋
このやるせない事情を解決するために stash をうまく使ってみてほしい。
例えば、○○の作業として、「企業登録画面を作成する」というタスクがあったとする。 そして、作業中に、△△の作業が必要であることがわかったとする(例えば、電話番号のバリデーションを共通化する等)。
こんなときのやり方である。
- ○○作業用の main ブランチを作成する(※1)
- ○○の作業を始める
- △△の作業が見つかった!
- ○○の作業を、いったん stash する(※2)
- △△のための sub branch を作成する(※1)
- △△の作業をする
- sub branch を commit する
- main に切り替えて、sub branch をマージする
- stash を復元する
- 復元時にコンフリクトがあったら修復する(※3)
- 元の○○の作業を再開する
補足する。
※1 mainブランチを作成する意図
- main のブランチを作っておいて、サブブランチの統合先を main ブランチだと決めておくと、サブブランチが作りやすくなる。
- ブランチ名は、プロジェクト内で規則を決めればよいが、例えば、 main ブランチは、末尾に /main を付けることにすると、↓こうなる。
- (例 main) feature/{issue-no}/create-company/main
- {issue-no} は、チケット番号(ブランチ名に Issue の番号を入れる規則にしておくと、必ず Issue を作ってから作業することができる)
- create-company は○○の作業名
- main <---- /create-company をメインブランチにすると、/create-company/xxx が作成できないので、/main を末尾につけておくとよい
- (例 sub) feature/{issue-no}/create-company/shared-phone-validation
- ブランチ名には相変わらず issue-no が含まれているし、このsub branch の作業が何キッカケで必要になったのかがわかる。
- サブブランチ化して作業すると、△△の作業に、あとから修正が必要だとなったときに、このサブブランチに戻って作業ができる
- コードレビューもサブブランチ単位に小さく依頼することができる
※2 stash の使い方
- 新規のファイルは stash から漏れるので -u のオプションを付ける
- stash は、保存時に stash 名も指定しておいた方がよい
- 保存時
- git stash save -u 'hoge'
- stash はログが残らないので、名前は、なんでもいい。"2023-08-21 09:00" とか、ぶつからない命名規則を自分で決めておくのもよさそう。
- 復元時
- stash pop を使うと消えてしまうので、apply で復元した方がよい。apply は消えないので。
- hogeの名前では復元できないので、git stash list で探して復元する。以下の例では、 hogeは stash@{0}で復元できる
(注) stash@{0}は、シングルクオートで囲うこと!。@や{} はシェルの変数を展開しようとするので。$ git stash list stash@{0}: On branch_name: hoge git stash apply 'stash@{0}'
※3 stash のコンフリクト
stash を復元するときに、コンフリクトが出るが、小さいコミットなので、コンフリクトも小さく対処はそんなに大変ではない。
まとめ
○○と△△の作業を見極めてから作業を始めるのは、なかなか面倒で手が止まりそうなので、 あとから別にまとめられそうな作業が見つかったら、いったん stash してサブブランチを作る方針がよさそうだ。 また、小さい修正で再修正の懸念がないものだったら、ブランチを分けなくてもコミットがまとまってるだけでよい場合もあると思う。
ちなみに、ビッグなコミットログを悲しいと思っているのは、あなただけではない!みんなが抱えている悩みだったりする。 かく言う私も、上記に紹介した解決策に気が付いたのは、けっこう最近なのだ。なんとなく、git 本には書いてあるような処方箋だけど。
いままで stash をあまり使ってこなかった人は、 stash して本当に保存されてるのか不安で躊躇すると思うのだけど、使ってるうちに慣れる!
コミットを小さく刻むと、1日1コミットが、当たり前に実現できるし、 そして、コミットすると気持ちがいいので、1日1回はコミットして、小さい達成感を味わいましょう。