私の所属している会社では、2年程前にバージョン管理システムをSubversionからGitに移行し、現在まで開発フローを試行錯誤してきました。ようやく形になってきたということで、守秘義務に接触しない程度に紹介&考察していきたいと思います。
形になってきたとはいえ、まだまだ試行錯誤中ですので色々なツッコミは大歓迎です。
現在の開発フローの俯瞰図
現在の開発フローを俯瞰してみると大体下記図のような感じになっています。途中で図を書くのが面倒になった都合上、Jenkinsさんが1人しか居ませんが、実際はmasterブランチの他にreleaseブランチも監視してもらっています。
以降この図を元に話を進めていきたと思います。
Gitoriousを利用して自由に開発
GitoriousというGitHubに似たサービスがあります。このGitoriousはオープンソースとしても公開されていますので社内に設置して利用する事が出来ます。
見た目はGitHubとだいぶ違いますが利用方法は似通っていて、まずプロジェクトの中央リポジトリが存在し、それを各人がフォークして開発をしていくスタイルになります。GitHubのPull request(GitoriousではMerge requestと呼ぶ)と同等の機能もあるので、俯瞰図にも書いてある通り非常にGitHubを利用した開発に近くなっていると思います。
Gitoriousを利用するメリット・デメリット
このGitoriousを利用した開発フローのメリットとしては以下が挙げられます。
- 必ずフォークしてから開発するので、仮に滅茶苦茶な実装をコミットしても周りに影響が無い。
- 周りに影響が無いので、Git初心者の社員にも心置きなくGitを弄り倒してもらう事が出来る。
- Pull request で変更内容がDiffで見れるので、コードレビューするのが楽になる。
- Pull request は独立したブランチになっているので、開発者はダメ出しされた後にPull requestに対して再度push出来る。
まぁ、GitHubを利用した場合と同じようなメリットですね。逆にデメリットとしては以下が挙がってきます。
- 管理者が休んだりサボったりするとあっという間にPull requestが溜まってしまう。
- 管理者、開発者共にGitの知識がかなり要求される。
- push, pull, merge, rebaseのルールを決めておかないとコンフリクト地獄に陥る可能性が大。
マスターブランチの運用と新規開発時のフロー
マスターブランチは開発の先端として扱っています。開発途中なのでバグが含まれている可能性がありますが、毎日・もしくはプッシュ後にナイトリー環境にデプロイしています。常に最新のコードをデプロイしておくことは重要で、バグの早期発見は勿論ですが、「プロジェクトの動いている感」を偉い方々に見てもらう狙いもあります(うちは自社企画が多いので…)
新規開発を担当する開発者は、mainlineのマスターブランチとローカルリポジトリのマスターブランチをPullで同期を取りつつ、作業毎にトピックブランチを切って開発を行っています。
開発が終わったらトピックブランチをリモートリポジトリにpushして、そのブランチをPull requestします。一連の流れをコマンドで表すと次の通りになります。
$ git checkout master
$ git pull mainline master
$ git checkout -b feature-hoge
--commit--
$ git pull --rebase mainline master
$ git push origin feature-hoge
管理者がPull requestを取り込む際は次のようにします。
$ git checkout master
$ git checkout -b merge-request/198
$ git pull git://xxxxx/project_name/mainline.git refs/merge-request/198
$ git rebase master
$ git checkout master
$ git merge merge-request/198 --no-ff
マスターブランチにマージする時に–no-ffオプションを付けることで下記コマンドで取り込んだトピックブランチ一覧を表示する事が出来ます。開発が活発な初期段階では大量にPull requestが飛んでくるのでどのトピックブランチまでマージ出来たか判断するのに有効です。
$ git log --oneline --abbrev-commit --merges master
リリースブランチの運用とメンテナンスフロー
リリースブランチはあるタイミングでマスターブランチから作成されます。このリリースブランチをプロダクション環境にデプロイし、サイト運用中に出た不具合の修正や次期リリースまでの繋ぎ機能の開発をこのブランチで行っていきます。
うちはサイトの性質上、且つ社内事情的にリリースの間隔がかなり空いてしまう場合が多いので、マスターブランチが次期リリースに向けての開発用、リリースブランチが現行安定版の保守用という感じにしています。
基本的なフローはマスターブランチの運用と同じで、開発者がトピックブランチをPull requestし、管理者が取り込む流れになります。マスターブランチでも直っていないバグ修正は、cherry-pickでマスターブランチに取り込む事もあります。
今後の課題
若干諦めてはいるのですが、マスターブランチとリリースブランチの内容が完全に違うモノになっていった時にcherry-pickすら厳しくなったらどうしようかな・・・と思ってたりします。まぁ、そんなになるまでリリースを温存しておくなって話なんですけどね…。社風の改革は開発フローを変えるより大変です。
あとこのフローとRedmineを使ったTiDDをどうシームレスに連携していくかが現在最大の課題となっています。例えばコミットログにcloses #1って記述したコミットをcherry-pickで各ブランチに取り込むと、二重に処理が走ったりなど…。この辺りはまだ手探りですね。
まとめ
Gitは非常に柔軟なバージョン管理システムだと思います。ここで紹介した開発フロー以外にも様々なフローがありますので、参考にしながら開発現場にあったやり方を見つけていくと良いんじゃないでしょうか。