Hatena::ブログ(Diary)

Yamashiro0217の日記 RSSフィード

2012-09-03

git flow でのチーム開発ワークショップ資料

11:43 | git flow でのチーム開発ワークショップ資料を含むブックマーク

この記事は会社内の別チームの方に、
僕の今のチームで git をどう運用してるかを
ワークショップ形式で説明するための資料である。

事前準備

gitgit-flow を入れておくこと

参考資料(Macgitgit-flowインストール)

- xcode cli toolインストール 
-- https://daw.apple.com/cgi-bin/WebObjects/DSAuthWeb.woa/wa/login?appIdKey=d4f7d769c2abecc664d0dadfed6a67f943442b5e9c87524d4587a95773750cea&path=%2F%2Fdownloads%2Findex.action
- homebrewインストール 
-- https://github.com/mxcl/homebrew/wiki/installation
- brewgitgit-flowインストール
-- >brew install git
-- >brew install git-flow

参考資料(Windowsgitgit-flowインストール:msysgist編)

- msysgistのインストール
-- http://code.google.com/p/msysgit/downloads/list?q=full+installer+official+git
- git-flowのために、util-linuxからgetopt.exeとlibintl3.ddlを入手
-- http://gnuwin32.sourceforge.net/packages/util-linux-ng.htm#download から「Complete package, except sources」 でダウンロードインストール
-- インストールディレクトリ(「C:\Program Files (x86)\GnuWin32」)の「bin\getopt.exe」と「bin\libintl3.ddl」をmsysgitインストールディレクトリのbin(「C:\Program Files (x86)\Git\bin」)にコピー
- git clone git://github.com/nvie/gitflow.git する
-- >cd gitflow
-- > git clone git://github.com/nvie/shFlags.git
-- 管理者権限で、contrib\msysgit-install.cmd "C:\Program Files (x86)\Git" を実行
 

前提

うちのチームの前提
- リリースは週1ぐらいを想定
- チームサイズは10人程度
- リモートリポジトリは各人もったりしないで一個

リリースサイクル早かったり人数多いと運用は変わるだろう。

git-flow とは

Vincent Driessen氏がブログに書いた"A successful Git branching model" というブランチモデルの導入を簡単にする git プラグインである
(日本語訳 http://keijinsonyaban.blogspot.jp/2010/10/successful-git-branching-model.html)

A successful Git branching model とは
http://d.hatena.ne.jp/Voluntas/20101223/1293111549
から引用すると

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


というモデルである.

git flow コマンドは上記モデルを助けるためのツールなので、
なるべく上記モデルを理解し、
git flowコマンドが裏側で何をやっているのかも理解しながら行なって欲しい

注釈
git flowが本当に何をやってるか詳しく知りたい人は、ソースを読もう。
https://github.com/nvie/gitflow
git プラグインは基本的にはシェルスクリプトだ。
例えばgit flow feature finishが何をやってるか見たければ
このソースの
https://github.com/nvie/gitflow/blob/develop/git-flow-feature
cmd_finishを見ればいい


git flow初期化

まずは二人一組になって欲しい。はーい。あぶれた人は先生と組みましょうね。
二人の名前はアリスとボブと名づける
(二人一組になれない人は一人二役でcloneするディレクトリAliceとBobと2つに分けて実行しよう。ScreenとかでWindowわけておくといいのでは)

アリスもボブもgit cloneをしてローカルにリポジトリクローンしよう

次にアリスもボブもgit flow initで、リポジトリ初期化を行なっておこう
色々と聞かれるが、git flowのFeatureブランチの名前などを聞かれている
基本はデフォルトで良い

#git flow init

Which branch should be used for bringing forth production releases?
   - master
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? [] 

git flow init -d を使うとすべてデフォルトの設定のままでコマンドが終わる

このときgit branchコマンドを実行するとdevelopブランチで作業してることになっているはずである

# git branch
* develop
  master

注記
ほんとうにまっさらなgitリポジトリでやってると、developブランチがremoteにないのでこの後の説明で怒られるので、
git push origin developしておこう。
ワークショップのとき、まっさらなリポジトリでやったので怒られた><)


アリスが新しい機能の作成を行うために Feature ブランチを切る

さて、新しい機能を作成しよう。

アリスコマンドラインから数値を受け取って、数値にしたがって、FizzBuzzを表示するタスクをやって欲しいと言われた。
(ワークショップなのでプログラムの内容は適当)

チケット番号は TSK48 とする。

まずは機能を作成する前に、Feature branchを切る。

Feature branchとは、将来に向けた機能を開発するためのブランチである。
日々の開発は基本的にはFeature branch上で行うことになる。

brach名には「チケット番号_簡単な説明」としている。
アリスは以下のようにgit flow start コマンドを実行しよう。

# git flow feature start TSK48_fizzbuzz
Switched to a new branch 'feature/TSK48_fizzbuzz'

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

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

     git flow feature finish TSK48_fizzbuzz


この時点で何が行われているかというと、feature/TSK48_fizzbuzzというブランチが作成され、
そのbranchがチェックアウトされた状態になっている。

アリスgit branchすると以下のようになる。

# git branch                                      
  develop
* feature/TSK48_fizzbuzz
  master

feature/TSK48_fizzbuzzが作られチェックアウトされている。

>>
注記
git を使うときは、しつこいぐらいに git branch , git status , git status -s,git status -bコマンドを使うべき。
自分がどこにいるかを確認しないとダメだからだ。
僕はzshコマンドプロンプトにブランチの状態と、statusの状態を自動で表示するようにしている。


まずアリスfizzbuzz.phpというのを以下のように作成した。
(プログラムの内容に明らかにミスがあるが説明の都合上なので見逃してくだしあ

<?php
$val = $argv[1];

if ($val % 3 == 0 && $val % 5 == 0) {
  echo 'FizzBuzz';
} elseif ($val % 2 == 0) {
  echo 'Fiz';
} elseif ($val % 5 == 0) {
  echo 'Buzz';
} else {
  echo $val;
}

そしてこれをaddしてcommitした(git commit -a でもいいけどね)

# git add fizzbuzz.php
# git commit -m "[TSK48] Fizzbuzz 作った"                 
[feature/TSK48_fizzbuzz 6cf76a9] [TSK48] Fizzbuzz 作った
 1 files changed, 13 insertions(+), 0 deletions(-)
 create mode 100644 fizzbuzz.php

注釈
コミットログにはチケット番号を含めるのが僕のチームのルールです


ボブとの協調作業の準備のためにpushを行う

fizzbuzzプログラマーの採用試験で出てくるぐらい難しいので、
ボブが作業に加わることになった。

アリスは、ボブとも作業を協調してできるように、
pushを行った。

git flow feature publish で remote リポジトリに push しよう。

# git flow feature publish TSK48_fizzbuzz
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 391 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/yamashiro/gitworkshop.git
 * [new branch]      feature/TSK48_fizzbuzz -> feature/TSK48_fizzbuzz
Already on 'feature/TSK48_fizzbuzz'

Summary of actions:
- A new remote branch 'feature/TSK48_fizzbuzz' was created
- The local branch 'feature/TSK48_fizzbuzz' was configured to track the remote branch
- You are now on branch 'feature/TSK48_fizzbuzz'

新しく、feature/TSK48_fizzbuzzがremoteに新しく作られ、pushされ、localブランチがremoteブランチをtrackされるようになった。

注記
ここで、error: The branch 'feature/TSK48_fizzbuzz' is not fully merged.
って出た人は、手動で
git branch -D feature/TSK48_fizzbuzz
を実行してください。


ボブの作業の開始。pullを行う

ボブは作業をはじめるために、pullを行う。
git flow を使って以下のようにコマンドを実行する。

# git flow feature pull origin TSK48_fizzbuzz
Unpacking objects: 100% (3/3), done.
Created local branch feature/TSK48_fizzbuzz based on origin's feature/TSK48_fizzbuzz.

これは「git checkout -b feature/TSK48_fizzbuzz origin/feature/TSK48_fizzbuzz」などとするのと一緒の作業である。
この作業でリモートにあるTSK48_fizzbuzzブランチを取得し、それを元にしてローカルにfeature/TSK48_fizzbuzzブランチが作成された。

さぁ、ボブも作業を始めよう
ボブは与えられた数値が100を超えてたら「Too big」と表示されるという機能をたすように言われたので以下のようにファイルを変更した。

<?php
$val = $argv[1];

if ($val >= 100) {
  echo 'Too big';
} elseif ($val % 3 == 0 && $val % 5 == 0) {
  echo 'FizzBuzz';
} elseif ($val % 2 == 0) {
  echo 'Fiz';
} elseif ($val % 5 == 0) {
  echo 'Buzz';
} else {
  echo $val;
}

ボブはプログラム描き上げたので、git commit -a しよう(addしてcommitってことです)

# git commit -am "[TSK48] 100以上だったらToo bigと表示するように"
[feature/TSK48_fizzbuzz 4492466] 100以上だったらToo bigと表示するように
 1 files changed, 3 insertions(+), 1 deletions(-)

ボブはお腹が減ったのでランチに行った

アリスも作業

アリスも作業しよう。
fizzbuzzで表示される文字列の前後に *Fizz*などといった飾り文字を表示しよう。

アリスは以下のようにプログラムを変更した。

<?php
$val = $argv[1];

if ($val % 3 == 0 && $val % 5 == 0) {
  echo '*FizzBuzz*';
} elseif ($val % 2 == 0) {
  echo '*Fiz*';
} elseif ($val % 5 == 0) {
  echo '*Buzz*';
} else {
  echo "*$val*";
}

作業完了したので、git commit -a しよう(addしてcommitってことです)

# git commit -am "[TSK48] 飾り文字を足した"
[feature/TSK48_fizzbuzz 4da4758] 飾り文字を足した
 1 files changed, 4 insertions(+), 4 deletions(-)

作業終わったんでボブとも作業を共有するためにpushしよう。コンフリクト解消したくないので、ボブより先にpushしたいしね!(という考えはあんまりよくないけど、コンフリクトだるいよねw)

# git push origin feature/TSK48_fizzbuzz
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 377 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To https://github.com/yamashiro/gitworkshop.git
   6cf76a9..4da4758  feature/TSK48_fizzbuzz -> feature/TSK48_fizzbuzz

ボブpushしようとする

ボブはランチから帰ってきたので、プログラムをテストし、作業をアリスと共有するためにpushしようとした。

# git push origin feature/TSK48_fizzbuzz
To https://github.com/yamashiro/gitworkshop.git
 ! [rejected]        feature/TSK48_fizzbuzz -> feature/TSK48_fizzbuzz (non-fast-forward)
error: failed to push some refs to 'https://github.com/yamashiro/gitworkshop.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

Oh!アリスが先にpushしているのでfast-forwardでないからrejectされた。

ボブは冷静にアリスの作業をpull --rebaseする。

# git pull --rebase origin feature/TSK48_fizzbuzz
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 3 (delta 1)
Unpacking objects: 100% (3/3), done.
From https://github.com/yamashiro/gitworkshop
>   6cf76a9..4da4758  feature/TSK48_fizzbuzz -> origin/feature/TSK48_fizzbuzz
First, rewinding head to replay your work on top of it...
Applying: 100以上だったらToo bigと表示するように
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging fizzbuzz.php
CONFLICT (content): Merge conflict in fizzbuzz.php
Failed to merge in the changes.
Patch failed at 0001 100以上だったらToo bigと表示するように

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

Oh!今度はpull --rebaseしようとしたらコンフリクトしてしまった。
コンフリクトを解消すべくボブはエディタを開いた

<?php
$val = $argv[1];

<<<<<<< HEAD
if ($val % 3 == 0 && $val % 5 == 0) {
  echo '*FizzBuzz*';
=======
if ($val >= 100) {
  echo 'Too big';
} elseif ($val % 3 == 0 && $val % 5 == 0) {
  echo 'FizzBuzz';
>>>>>>> 100以上だったらToo bigと表示するように
} elseif ($val % 2 == 0) {
  echo '*Fiz*';
} elseif ($val % 5 == 0) {
  echo '*Buzz*';
} else {
  echo "*$val*";
}

ボブはアリスに作業内容を聞き、コンフリクトを解消した。fizzbuzz.phpの内容は以下のようになった。

<?php
$val = $argv[1];

if ($val >= 100) {
  echo '*Too big*';
} elseif ($val % 3 == 0 && $val % 5 == 0) {
  echo '*FizzBuzz*';
} elseif ($val % 2 == 0) {
  echo '*Fiz*';
} elseif ($val % 5 == 0) {
  echo '*Buzz*';
} else {
  echo "*$val*";
}

コンフリクトを解消したのでボブはgit addしてgit rebase --continueする

# git add fizzbuzz.php 
# git rebase --continue
Applying: 100以上だったらToo bigと表示するように

rebaseが終わったのでpushする

# git push origin feature/TSK48_fizzbuzz
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 399 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To https://github.com/yamashiro/gitworkshop.git
   4da4758..baf3e5d  feature/TSK48_fizzbuzz -> feature/TSK48_fizzbuzz

作業が終わったのでボブはレビュー依頼を投げた(うちのチームだとアトラシアン製品のCrucibleを使ってレビューしている)。

アリス feature を finish する

ボブの作業が終わり、レビューも通ったのでアリスfizzbuzz機能が完了したと考えたのでfeature を finish する(普通だったらボブがそのままやっても良さそうだけど、ワークショップの都合上)。
finishとはfeatureブランチをdevelopにマージし、ブランチを削除するなどの作業である。

アリスはまずボブの作業をpullする。

# git pull --rebase origin feature/TSK48_fizzbuzz                                     
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 3 (delta 1)
Unpacking objects: 100% (3/3), done.
From https://github.com/yamashiro/gitworkshop
   4da4758..baf3e5d  feature/TSK48_fizzbuzz -> origin/feature/TSK48_fizzbuzz
Updating 4da4758..baf3e5d
Fast-forward
 fizzbuzz.php |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

次に、他の人の作業を自分のbranchにrebaseしておこう。
リベースしてないと悲しみが生まれるからだ。
詳細はgit flow feature finishした後にリモート更新で気づくと悲しい問題への対処法を参照されたし。

# git pull --rebase origin develop                  
From https://github.com/yamashiro/gitworkshop
 * branch            develop    -> FETCH_HEAD
Current branch feature/TSK48_fizzbuzz is up to date.

注記
ここで「fatal: Couldn't find remote ref develop」出る人は、リモートリポジトリにdevelopが無い人


幸いなことに他の人と作業はかぶらなかったようだ。
普通に開発してると、ここでコンフリクトが起きたりするので、冷静にコンフリクトを解消してrebase continueしていこう。



次に git feature finishする。

# git flow feature finish TSK48_fizzbuzz
Switched to branch 'develop'
Merge made by recursive.
 fizzbuzz.php |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)
 create mode 100644 fizzbuzz.php
Deleted branch feature/TSK48_fizzbuzz (was baf3e5d).

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

ログを見て分かる通り、feature/TSK48_fizzbuzzブランチをdevelopにマージし、feature/TSK48_fizzbuzzを削除している。
自分の手でやるとしたら、

# git checkout develop 
# git merge feature/TSK48_fizzbuzz
# git branch -d feature/TSK48_fizzbuzz

と同等である。

ここでgit log --graph コマンド、gitkコマンドや、MacのSourceTreeなどで状態を確認すると、以下の通りになって、マージがうまく行ってることがわかるだろう。

f:id:Yamashiro0217:20120902142028p:image

この変更をdevelopにpushし、必要のなくなったリモートブランチを削除しておこう。

# git push origin develop
Counting objects: 1, done.
Writing objects: 100% (1/1), 246 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://github.com/yamashiro/gitworkshop.git
   20148a8..8468e85  develop -> develop
# git push  origin :feature/TSK48_fizzbuzz
To https://github.com/yamashiro/gitworkshop.git
 - [deleted]         feature/TSK48_fizzbuzz


ボブ リリースブランチを切る

さてfizzbuzzもできたし、他のチームの作業もキリがよくなったということなので、リリース作業を行える状態になった。

そこでボブがリリース作業を行うこととした。
その前に、ボブのローカルのブランチは削除されていないので、ローカルのブランチを削除しておこう。

# git checkout develop
# git branch -d feature/TSK48_fizzbuzz

次に develop を 最新のものにpullしておく

# git pull --rebase origin develop
From https://github.com/yamashiro/gitworkshop
 * branch            develop    -> FETCH_HEAD
Updating 20148a8..8468e85
Fast-forward
 fizzbuzz.php |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)
 create mode 100644 fizzbuzz.php

次にリリースブランチを作成する。バージョンは1.0.0とし、git flow relase startしよう。

# git flow  release start 1.0.0
Switched to a new branch 'release/1.0.0'

Summary of actions:
- A new branch 'release/1.0.0' was created, based on 'develop'
- You are now on branch 'release/1.0.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.0'


また、このブランチをpushしておこう。

# git flow release publish 1.0.0                         
Unpacking objects: 100% (1/1), done.
Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/yamashiro/gitworkshop.git
 * [new branch]      release/1.0.0 -> release/1.0.0
Already on 'release/1.0.0'

Summary of actions:
- A new remote branch 'release/1.0.0' was created
- The local branch 'release/1.0.0' was configured to track the remote branch
- You are now on branch 'release/1.0.0'


これは 「git push origin release/1.0.0」して、「git branch --set-upstream release/1.0.0 origin/release/1.0.0 」と同様である。

さて、このリリースブランチを元に、検証環境などに環境を作って、品証やテスト、動作確認などを行う。

アリスプログラムバグに気づく

アリスが検証環境でテストしていると、3のときにFizzと出力されるべきなのが2のときに出力されていまってるではないか!(普通は自動テストで発見したり、その前に手で見つけられると思うけど、話の都合上ですよ)

アリスはリリースブランチ上でこのバグを修正する。
まずはリリースブランチを取得する。

# git flow release track 1.0.0                                [/Users/yamashiro/tmp/Alice]
Branch release/1.0.0 set up to track remote branch release/1.0.0 from origin.
Switched to a new branch 'release/1.0.0'

Summary of actions:
- A new remote tracking branch 'release/1.0.0' was created
- You are now on branch 'release/1.0.0'


これは 「git checkout -b release/1.0.0 origin/release/1.0.0」と同様である。

さて、アリスはリリースブランチ上でバグを修正してファイルを以下のようにした。

<?php
$val = $argv[1];

if ($val >= 100) {
  echo '*Too big*';
} elseif ($val % 3 == 0 && $val % 5 == 0) {
  echo '*FizzBuzz*';
} elseif ($val % 3 == 0) {
  echo '*Fiz*';
} elseif ($val % 5 == 0) {
  echo '*Buzz*';
} else {
  echo "*$val*";
}

これをadd commitしpushする。

# git commit -am "Fizzになる条件が2になっていたのを3にした"
[release/1.0.0 2673c89] Fizzになる条件が2になっていたのを3にした
 1 files changed, 1 insertions(+), 1 deletions(-)
# git push  origin release/1.0.0                                       
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 367 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To https://github.com/yamashiro/gitworkshop.git
   8468e85..2673c89  release/1.0.0 -> release/1.0.0

この状態でさらに検証環境にデプロイなどをし確認を取る。

ボブリリース作業を完了させる

検証環境での確認が終わったのでボブがリリース作業を完了させる
ここでgit flow release finishを行う。

その前にアリスの変更を取得しておこう(設定によっては release finishだけでいいんだけど)。

#git pull --rebase origin release/1.0.0

そして release finish を行う

#git flow release finish 1.0.0

エディタが立ち上がるのでリリースメッセージを入力する

1.0.0 のリリース
#
# Write a tag message
#


エディタを終了すると以下のように表示される。

".git/TAG_EDITMSG" 4L, 48C written
Switched to branch 'develop'
Merge made by recursive.
 fizzbuzz.php |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
Deleted branch release/1.0.0 (was 2673c89).

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

何がおきたかというと、リモートの変更をすべて取得し、
リリースブランチをmasterにマージ、
masterブランチに1.0.0のタグを付け、
リリースブランチをdevelopにマージ、
リリースブランチを削除している。

このとき git log --graphやツールで見ると以下のような状況になっている。

f:id:Yamashiro0217:20120902142030p:image

master developの状態をpushしよう。

# git push origin develop
()
# git checkout master
()
# git push origin master

タグの情報もpushする

# git push origin refs/tags/1.0.0
Counting objects: 1, done.
Writing objects: 100% (1/1), 174 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://github.com/yamashiro/gitworkshop.git
 * [new tag]         1.0.0 -> 1.0.0

これでリリース完了である。
リモートに作った relaseブランチを削除しておこう

# git push  origin :release/1.0.0
To https://github.com/yamashiro/gitworkshop.git
 - [deleted]         release/1.0.0

また、アリスも自分のローカルに残ったタグを「git branch -d release/1.0.0」で削除しておこう
またタグ情報なども 「git fetch --tags」で取得しておこう

アリス致命的なバグに気づく

リリースした翌日。アリスは致命的なバグに気がつく。
Fizzと表示すべきところがFizではないか!(すぐ気づくだろうというツッコミは受けないw)

すぐに修正しリリースするために、masterをベースにhotfixブランチを作成しよう。ついでにdevelpもpullしとく

# git checkout develop
# git pull --rebase develop
()
# git checkout master
Switched to branch 'master'
Your branch is behind 'origin/master' by 6 commits, and can be fast-forwarded.
# git pull
Updating 20148a8..6644b74
Fast-forward
 fizzbuzz.php |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)
 create mode 100644 fizzbuzz.php

さてgit flow hotfix startでmasterを元にhotfixブランチを作成する。バージョンを1.0.1としよう。

# git flow hotfix start 1.0.1
Switched to a new branch 'hotfix/1.0.1'

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

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

     git flow hotfix finish '1.0.1'


アリスバグを修正しadd commitした

# git commit -am "FizというスペルミスをFizzに修正"
[hotfix/1.0.1 7010300] FizというスペルミスをFizzに修正
 1 files changed, 1 insertions(+), 1 deletions(-)

修正、確認が終わったので、git flow hotfix finishする。

# git flow hotfix finish 1.0.1

するとエディタが立ち上がるので例えば以下のように入力する

Fiz というスペルミスのバグを緊急リリース
#
# Write a tag message
#


終わると以下のような表示になる。

".git/TAG_EDITMSG" 4L, 85C written
Switched to branch 'develop'
Merge made by recursive.
 fizzbuzz.php |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
Deleted branch hotfix/1.0.1 (was 7010300).

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


masterへのマージ、タグ付、developへのタグ付、ローカルのブランチの削除が行われた。

最後にmasterとdevelop、タグをpushしておく

# git push origin develop
()
# git checkout master
()
#git push origin master
()
# git push origin refs/tags/1.0.1  
()

まとめ

git flow を使うことでのチーム開発の流れが理解いただけただろうか。
可能であればボブとアリスを入れ替えて再度やってみて欲しい。

リンク元