Gitのベストプラクティクスっぽいもの

だいたいこれらに書いてあることを考えている。

基本的にGit Successful Branch Modelで運用する。git-flowを入れて使っているけど、手でやってもそんなに面倒ではないし好きなようにしたらよさそう。

Subversionを個人で使っていたころはブランチはよくわからないけど恐しいものだったけど、Gitを使いはじめてだいぶ親しめるようになった。
文字通り、ブランチ、枝である。気軽に扱えるということは理解の助けにもなる。

コミットの単位

論理的に最小限度のコミットをつくる。「こういう機能を実装した」っていうコミットはできるだけ避けたほうがいいと思っている。
コミットの粒度はテストを書いていると感覚が掴みやすい。

たとえばActiveRecordのバリデーションのテストを書くとき、異常値と正常値についてテストと実装を書く。余裕があれば境界値のテストまで含めてひとつのコミットとする。
コミットの単位は自分の脳のバッファの量に合わせるとよさそう。ロールが絡む認証のテストは条件分岐が複雑になるので異常値ひとつについてテストと実装を書いたらコミットすることもある。
実装が一通り終わったら

実装を進めていくとバリデーションに通らないでほしい (あるいは通ってほしい) ときに予期せぬ挙動をしたりするので境界値のテストを足す。この時、ブランチを切っておく。
fix/user-name-validation みたいな。論理的にまとまりのあるいくつかのコミットをまとめるものとしてブランチを扱うことで、たとえばバリデーションの修正だけ先に開発ブランチにマージすることができる。
もしバリデーションの修正がある機能開発ブランチの中にだけ存在していると、機能の開発に目処がつくまで修正は開発ブランチに取り込まれず、機能開発ブランチに対してバグ修正と機能の提供というふたつの責務を負わせることになる。
また、長引けば長引くほどconflictの危険性も高まる。conflictしないことに越したことはない。まめにコミットしておけばむだなconflict解決を減らせる。はず。

ブランチの命名規則はそれほどクリティカルではないから好きにしたらいいとおもうけど、たとえばバグ修正は fix/ で始まる、とかそういう簡単な規約をつくっておくと便利そう。
そういう規約を設けることでたとえばリポジトリブラウザで fix/ 以下にあるバグ修正ブランチを一覧する、みたいなのも簡単に実現できておもしろそう。

歴史修正について

あまりしないけど、バグ修正のコミットとかはよくrebaseする。Gitはローカルでいくらでもできるのだから、branch切りまくってrebaseとか実践していくほうがずっとためになる。
というか、怖くなったら適当なリポジトリを作って試すことができる。便利。

あと、Git Successful Branch Modelでも言及されているけど、基本的にブランチのマージは --no-ff で行う。

コミットメッセージについて

Railsとかはジェネレータを供えている。どういうコマンドやオプションでファイルが生成されたか記録しておいて不便しないのでジェネレータを走らせるたびにコミットしている。

Zshだとfcというビルトイン関数がある。

rails new myapp -T
git add -A; git commit -m "$(fc -l -n -1)" # rails new myapp -T

ActiveRecord::Migrationを走らせるたびにどのバージョンにマイグレートしたのか記録しておきたい。

bundle exec rake db:migrate
git commit -m "Migrate $(bundle exec rake db:version)" # Migrate Current version: 20124081204

コミットメッセージは現在形を使うようにする。歴史修正が容易く行われるので、「このコミットは) 〜という変更を及ぼす」と読み下せるようなメッセージがよいと思う。
詳しいメッセージは空行を挟んでから書くか、重要度が低そうならgit notesにでも。