注目の記事

AWSチーム社内勉強会「git-flow」レポート

2015.01.21

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、虎塚です。

先日、git-flowをテーマに社内勉強会を行いました。講師役は、AWSチームの都元さんにお願いしました。

クラスメソッドではお客様向けにクラスメソッド・メンバーズというサービスを運営しています。このサービスの会員向けポータルサイトの開発で、Gitとgit-flowを採用しています。そこで、メイン開発者である都元さんにgit-flowの概要を話してもらって、皆で聞こうということになりました。

いつもはAWSコンサルティング部のメンバーで実施している勉強会ですが、今回はテーマが開発寄りなので、AWSソリューション部の人たちにも参加してもらいました。AWSソリューション部は、システム開発を中心に行っている部署です。

git-flow勉強会(秋葉原オフィスの様子)

上は秋葉原オフィスの会場です。札幌オフィス、上越オフィス、リモートワークのメンバーも、Googleハングアウトで接続して開催しました。

git-flow勉強会(Googleハングアウトの様子)

それでは、勉強会の内容をレポートします。

git-flowの概要

素のGitでは、コミットを1回行うとmasterという名前のブランチが作成されます。それ以外の情報、たとえば、どういうふうにbranchを作成するとよいかといった指針は、特に与えられません。そのため、Gitをどのように使えば開発フローが整理できるかという議論が、あちこちのコミュニティで行われてきました。

git-flow

2010年頃、上のブログエントリで、あるbranching modelが提案されました。branching modelとは、ブランチをいつ作成し、いつマージするかのルールを定めたものです。これにgit-flowという名前がついて広まりました。

git-flowに特徴的な5つのブランチの役割を順に見ていきます。

  • master
  • develop
  • feature
  • release
  • hotfixes

masterブランチ

masterブランチは、リリースのタイミングでだけコミット(マージコミット)するブランチです。

日頃の開発作業では、masterブランチに直接コミットしないようにします。そうすると、masterブランチのHEADに、最も最近リリースされたソースコードがある状態になります。

別の言い方をすると、このような使い方をすると決めたブランチが、git-flowのmasterブランチです。

developブランチ

developブランチは、開発を進めるためのブランチです。masterブランチを親として作成します。

featureブランチ

featureブランチは、特定の機能に関する実装をするためのブランチです。developブランチを親として作成します。実装が完了したら、featureブランチはdevelopブランチにマージします。

このブランチは、機能単位に作成されるので、リリースバージョンを飛び越えて継続することもあります。

releaseブランチ

releaseブランチは、リリース作業をする場所です。リリースの準備をはじめる時に、developブランチを親として作成します。リリース終了時、releaseブランチはmasterブランチとdevelopブランチの両方にマージします。

リリース作業とは、たとえば次のような作業が考えられます。

  • ビルドスクリプトに書いたリリースバージョン番号を繰りあげる
  • developブランチから引きついでしまったバグを直す
  • 今回のリリースに入れたくない機能を取りのぞく

hotfixesブランチ

hotfixesブランチは、リリース済みのコードに重大なバグが見つかった時に修正する場所です。masterブランチを親として作成します。修正完了後、hotfixesブランチはmasterブランチとdevelopブランチの両方にマージします。

補足: supportブランチ

master、develop、feature、release、hotfixesの5種類のブランチに加えて、supportブランチを作成する場合があります。

supportブランチは、旧バージョンの保守をする場所です。masterブランチを親として作成します。

masterのバージョンが上がっても、masterにマージせず、使い続けます。このブランチは、master以外のブランチで唯一、リリース対象になります。

git-flowをサポートするツール

git-flowをサポートするためのGitの拡張コマンドがあります。

ちなみに、GUIクライアントのSourceTreeにも同様の機能が組み込まれています。詳細は次の記事をご覧ください。

前述のとおり、素のGitでgit initを実行すると、masterブランチが作成されます。git-flowコマンドでgit flow initを実行すると、developブランチが作成されて、カレントブランチがdevelopになります。

また、次で説明するとおり、featureブランチやreleaseブランチの管理もgit-flowコマンドで簡単に行えます。

このツールを使う利点は、git-flowを運用していくために必要な操作をコマンド化してくれたことで、導入の敷居を下げられることです。

git flow featureコマンド

featureブランチでの作業開始時のコマンドは、次のようになります。

 git flow feature start ブランチ名

featureブランチでの作業終了時のコマンドは、次のようになります。

 git flow feature finishブランチ名

このコマンド1つで、featureブランチをdevelopブランチにマージして、featureブランチ自体を削除してくれます。

git flow releaseコマンド

releaseブランチでの作業開始時のコマンドは、次のようになります。

 git flow release start リリースバージョン

releaseブランチでの作業終了時のコマンドは、次のようになります。

 git flow release finish リリースバージョン

この時に行われる作業は少し複雑です。

  • releaseブランチをmasterブランチにマージする
  • そのマージコミットにリリースバージョンのタグをつける
  • releaseブランチをdevelopブランチにマージする
  • 使い終わったreleaseブランチ自体を削除する

これら4つの作業を、コマンド1つで実行してくれます。

補足

リモートリポジトリには、基本的にmasterブランチとdevブランチをpushします。git-flowコマンドは便利ですが、finishコマンドでリモートのブランチまでは削除してくれません。

質疑応答とディスカッション

Q: git-flowコマンドで操作した後、リカバリはできますか?
A: push前ならいくらでもできます。pushした後はgit-reflogでがんばろう。
Q: hotfixesブランチの内容は、直接リリースしないもの?
A: しません。hotfixesはmasterにマージすることを前提に作成します。
Q: hotfixesは重要な修正なんですよね? supportブランチにもマージしていいですか?
A: はい。また、supportブランチ用にhotfixesブランチを生やしてもよいと思います。そのあたりはチームでルールを決めて運用します。
Q: featureブランチやreleaseブランチをfinishしたら、masterブランチにマージされますが、同時にsupportブランチにもマージできますか?
A: できません。
能登さん: supportブランチは保守用ですが、本気で保守していくなら、リポジトリを分けた方が管理しやすいと思います。

コミットグラフの例

Q: git-flowではrebaseやsquashはするんですか? 皆さんやってますか?
A: git-flowでは、rebaseやsquashについてのルールを定義していません。してもしなくてもよいです。
修司さん、梶原さん: rebaseはしますが、squashはしてません。
修司さん: rebaseでも逆マージでもいいから、事前にコンフリクトを解消しよう!
能登さん : rebaseすることで、履歴を見た時にどこを基点に改修したかが分かりやすくなるのが重要。

デモンストレーション

冒頭でご紹介したクラスメソッド・メンバーズのポータルサイトのバージョン1.31のリリース作業(正確には、デプロイ前までのリリース作業)を、都元さんがリアルタイムで見せてくれました。

$ git flow release start 1.31
Switched to a new branch 'release/1.31'

Summary of actions:
- A new branch 'release/1.31' was created, based on 'develop'
- You are now on brance 'release/1.31'

Follow-up actions:
- Bump the version number now!
- Start committing last-minute fixes in preparing your release
- When done, run:

    git flow release finish '1.31'

git flow release startで、この後にやるべきことまで表示してくれるんですね。

それから、ビルドスクリプトのバージョン番号を書き換えて、git add、commitします。最後に、次のコマンドでgit上のリリース作業が完了しました。

$ get flow release finish

感想

git-flowの概要をひととおり知ることができました。都元さん、ありがとうございました! git-flowを導入したからといって単純に決定されないフローもあり、それらの運用はチームごとに決めていく必要があることも分かりました。

AWSチームの仕事では、いわゆる開発作業は少ないですが、スクリプトやCloudFormationテンプレートなどの読み書きは行います。今回学んだことを活用しようと思います。

それでは、また。