読者です 読者をやめる 読者になる 読者になる

A successful Git branching model を補助する git-flow を使ってみた

git

git-flow という git の運用を補助するプラグインを使ってみたので、その過程をメモしてみました。

そもそも git を採用理由なども書いていきたいと思います。

git を採用した理由

まず何よりも git を採用した理由ですが、日本語の本がたくさんある。Subversion のように気軽にブランチを切ったりマージが出来ない方法では「開発スピードにバージョン管理がついてこれない」という結論に至りました。

そこで svn から git へ以降の準備を進めています

なぜ hg や bzr ではないのか

git-svn を前々から使っていて rebase のありがたみや branch を気軽にきる運用になれていたからというのもありますが、なにより身近に詳しい人が多いというのが一番です。

Tower や GitX という素敵な GUI があるのも魅力の一つですね。

A successful Git branching model とは

[A successful Git branching model] について簡単に説明すると以下のような運用になります

  • master ブランチは tag 専用とする
  • 新機能開発は feature ブランチで行う
  • 細かい開発は develop ブランチで行う
  • release ブランチはタグを打つための作業を行う
  • hotfix ブランチはバグフィックスを行う専用のブランチで develop と master に反映する

この運用がとても気に入って、社内での導入を進めています。
この運用を補助してくれる git-flow という git プラグインを触ってみたところとてもよかったので、紹介したいと思います。

git-flow とは

[A successful Git branching model] を運用しやすくする git プラグインです。

git-flow を使ってみた

まず何よりもリポジトリを作るところから始めてみます。

まず git flow init で方針を決定します。デフォルトで運用してみましょう。

% mkdir snowflake
% cd snowflake
% git flow init     
Initialized empty Git repository in /private/tmp/snowflake/.git/
No branches exist yet. Base branches must be created now.
Branch name for production releases: [master] 
Branch name for "next release" development: [develop] 

How to name your supporting branch prefixes?
Feature branches? [feature/] 
Release branches? [release/] 
Hotfix branches? [hotfix/] 
Support branches? [support/] 
Version tag prefix? [] 

デフォルトブランチは develop です。master はタグ専用です。

% git branch
* develop
  master

ここで適当にファイルを作ってコミットしてみます

% mkdir src
% touch src/snowflake.erl
% git add src/snowflake.erl
% git commit
[develop 7ab2284] コミット
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 src/snowflake.erl

新しい機能を実装するので feature ブランチを切りましょう。
spam というブランチを作ります

% git flow feature start spam
Switched to a new branch 'feature/spam'

Summary of actions:
- A new branch 'feature/spam' was created, based on 'develop'
- You are now on branch 'feature/spam'

Now, start committing on your feature. When done, use:

     git flow feature finish spam
% git branch
  develop
* feature/spam
  master

ブランチが作成されたので、ちょっとコードを書き換えてコミットします。

% git diff
diff --git a/src/snowflake.erl b/src/snowflake.erl
index e69de29..7006ac1 100644
--- a/src/snowflake.erl
+++ b/src/snowflake.erl
@@ -0,0 +1 @@
+-module(snowflake).

コミット後、この feature/spam ブランチを終了します。

% git flow feature finish spam
Switched to branch 'develop'
Updating 7ab2284..755cedb
Fast-forward
 src/snowflake.erl |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
Deleted branch feature/spam (was 755cedb).

Summary of actions:
- The feature branch 'feature/spam' was merged into 'develop'
- Feature branch 'feature/spam' has been removed
- You are now on branch 'develop'

develop に無事マージされて、feature/spam ブランチを削除されました。
ではリリースブランチを作りましょう。リリース後のバージョンは 1.0 とします。

% git flow release start 1.0
Switched to a new branch 'release/1.0'

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

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.0'

リリースブランチが作成されました。
ここで、リリース用に少し変更します。
ebin/snowflake.app を追加してコミットします。

% git branch
  develop
  master
* release/1.0
% git add ebin/snowflake.app
% git commit
[release/1.0 e213f39] .app を追加
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 ebin/snowflake.app

さてリリースブランチの作業が終わったので終了します。

% git flow release finish 1.0
Switched to branch 'master'
Merge made by recursive.
 src/snowflake.erl  |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 ebin/snowflake.app
 create mode 100644 src/snowflake.erl
Switched to branch 'develop'
Merge made by recursive.
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 ebin/snowflake.app
Deleted branch release/1.0 (was e213f39).

Summary of actions:
- Latest objects have been fetched from 'origin'
- Release branch has been merged into 'master'
- The release was tagged '1.0'
- Release branch has been back-merged into 'develop'
- Release branch 'release/1.0' has been deleted

% git tag
1.0
% git branch
* develop
  master

master と develop にリリースブランチの変更がマージされました。
さらに 1.0 のタグが打たれて、現在のブランチが develop に変更されます。

さて最後に hotfix を当ててみます。
バグを修正した後のバージョン番号は 1.1 にしましょう。
1.1 は master の最新版からブランチが作成されるので 1.0 がベースです。

% git flow hotfix start 1.1
Switched to a new branch 'hotfix/1.1'

Summary of actions:
- A new branch 'hotfix/1.1' was created, based on 'master'
- You are now on branch 'hotfix/1.1'

Follow-up actions:
- Bump the version number now!
- Start committing your hot fixes
- When done, run:

     git flow hotfix finish '1.1'

src/snowflake.erl に -author(voluntas) を追加してコミットしました

% git commit
[hotfix/1.1 25a5e74] Fix: author を追加
 1 files changed, 2 insertions(+), 0 deletions(-)

これで hotfix は終了です、終了しましょう。

% git flow hotfix finish 1.1
Switched to branch 'master'
Merge made by recursive.
 src/snowflake.erl |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
Switched to branch 'develop'
Merge made by recursive.
 src/snowflake.erl |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
Deleted branch hotfix/1.1 (was 25a5e74).

Summary of actions:
- Latest objects have been fetched from 'origin'
- Hotfix branch has been merged into 'master'
- The hotfix was tagged '1.1'
- Hotfix branch has been back-merged into 'develop'
- Hotfix branch 'hotfix/1.1' has been deleted

master で新しい tag 1.1 がきられ、
develop にも変更がマージされました。

これが git-flow の簡単な動きです。実際は release ブランチや feature ブランチで rebase を行うこともあるでしょう。

こんなに単純ではありませんが、継続的に開発とリリースを行う場合はこの運用は個人的にはとても気に入っています。

実際積極的に開発やリリースを行うためには、なんかしらの運用にそって進める必要があります。もちろんチーム全員が git をある程度理解していたりするのは前提ですが ... 。

あまり日本では紹介されていない git-flow を自分が試すついでに紹介してみました。

これを機会にこの運用方法がもっと広まればと思います。