< マップリテラル | アメリカと言っても広うござんす >
2010/02/21
gitのワークフロー
仕事でgitを使い始めた。分散SCMを使ったのは初めてだったので最初は モデルを頭の中に作るのに苦労したが、自分なりのワークフローが 何となく出来てきたのでメモっとく。 gitの機能のまだほんの一部しか使ってないと思うけど。
まず案件の前提。
- 開発者は10数人。
- 開発はチケット毎にパッチを作ってレビューを受ける。
- 本家のリポジトリのブランチは開発バージョンに沿って切られており、 複数バージョンの開発が同時進行してる。
以下のワークフローはこの前提のもとでの作業。 前提が違えばフローも違ってくると思われる。
- リモートリポジトリをミラーしているブランチ
(e.g. origin/version1.1 に対する version.1.1 とか)
は原則として完全に同期させとく。以下のコマンドは適宜実行する。
$ git checkout version1.1 $ git fetch $ git fetch --tags $ git merge origin/vesion1.1
- チケットが来たら、メインのブランチからトピックブランチを切って移動。
トピックブランチはwork-* と名づけている。
$ git branch work-FOO $ git checkout work-FOO
- 作業してこまめにコミット。この時のコミットログは自分しか見ないのでメモ程度で良い。
$ git commit -a -m 'simple log'
- 作業が終了したら(あるいは適宜)、メインから上流の変更を取り込み。
$ git merge version1.1
- conflictしたら編集して、以下の手順で解決。
$ git add source/with/conflict.cl $ git commit -m 'conflict resolution'
- mergeが済んでテストも通ったら、パッチ作成用ブランチを作る。
パッチ作成用ブランチはwrap-*と名づけている。
$ git checkout version1.1 $ git branch wrap-FOO $ git checkout wrap-FOO
- 作業ブランチから変更を取り込み。この時--squashして、コミットをひとつにまとめる。
また、ちゃんとしたフォーマットに沿ったcommit logを用意してコミットする。
$ git merge --squash work-FOO $ git commit -F commit.log
- これがうまくいったら、メインブランチに変更をマージ。というのは、
パッチをレビューに回すスクリプトが別にあって、
こいつがorigin/${version}と${version}間のパッチを作るようになってるもんで。
パッチを送ったらメインブランチはリモートと同期させておく。
(wrap-FOOをマージした状態のままリモートからmergeするとパッチの順番が
前後して色々面倒になるので)
$ git checkout version1.1 $ git merge wrap-FOO $ パッチ生成、レビューに回す $ git reset origin/version1.1
- パッチが受理されて本家にpushされたら、wrap-FOOは消していい。
メインブランチもreset --hardでリモートに合わせとく。
work-FOOの方は、後で問題が出てパッチがrevertされた時に使うかもしれないので
とりあえず取っておく。
$ git branch -D wrap-FOO $ git reset --hard origin/version1.1
wrap-* が必要なのかどうかはまだよくわからない。 こうして書いてみるとversion1.1に直接merge --squashしちゃってもいい感じだけれど、 wrap upからパッチ作成の段階で試行錯誤してる時期があって (rebase -iとか使ってみたり)、 その間に別のトピックブランチを切る必要が出てきた時に 手つかずのversion1.1がある方が便利だったので、こういうフローにした。 全部merge --squash一発で済むならwrap-*を省いてもいいかも。
もっと使い込んだら変わってくるかもしれないけど、今のところはこんな感じ。
Tag: Programming
anon (2010/02/21 15:25:41):
shiro (2010/02/21 21:54:51):