ボブとアリスのgit-flow(和訳)
登場人物
( ゚⊇゚):ボブ。PL。趣味はボスのフェラーリでこっそりドライブすること
(・∠・`)乙:アリス。PG。最近流行りのgit系女子。今回のプロジェクトでgit-flowを初めて使う
ボス:ボス。愛車フェラーリ
git-flowの導入
( ゚⊇゚)「Hi、アリス。今度のプロジェクトでgit-flowを使ってみようと思うんだけど、どうだい?」
(・∠・`)乙「git-flow? なにそれ?」
( ゚⊇゚)「git-flowは最もクールなgitブランチワークの補助ツールさ!」
(・∠・`)乙「。。。」
( ゚⊇゚)「これを使えば勝手なブランチやリリースタグがどれとかいった混乱を防ぐことができるんだよ」
(・∠・`)乙「面白そうね。ぜひ使ってみましょう!」
( ゚⊇゚)「じゃ、git-flowのインストールからだ。インストールは簡単だよ。portコマンドで一発さ」
$ sudo port install git-flow
git-flowの利用開始
( ゚⊇゚)「インストールができたら、git-flowプロジェクトを作成しよう。」
$ 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では、その時の設定を決めることができるのさ。特に理由がないならそのままEnterでOKだよ」
(・∠・`)乙「OKボブ。全部Enterするわ」
機能を追加する
( ゚⊇゚)「これで準備は整った。作業を始めるよ。作業開始もgit flowコマンドを使うんだ。作業用のブランチを作成して、サクッとHelloWorldを作ってくれ。ブランチ名はhelloだ」
$ git flow feature start hello Switched to a new branch 'feature/hello' Summary of actions: - A new branch 'feature/hello' was created, based on 'develop' - You are now on branch 'feature/hello' Now, start committing on your feature. When done, use: git flow feature finish hello
(・∠・`)乙「git branchを使ってないけど、ブランチって作成されるのかしら?」
( ゚⊇゚)「yes! git-flowを使ったらブランチワークは概ねgit flowで作業するんだよ。ブランチも自動的に作成されているよ。git branchで確かめてごらん。」
$ git branch develop * feature/hello master
(・∠・`)乙「ブランチが3ついるわ。helloじゃなくてfeature/helloになっているけど、あとdevelopというブランチもいるわ」
( ゚⊇゚)「OKアリス。ここで各ブランチについて説明しよう。」
( ゚⊇゚)「git-flowではブランチ名にお約束があって、勝手なブランチは作ることができないんだ。使えるブランチは以下のとおりだ」
- master
- develop
- feature/***
- hotfix/***
- rerease/***
( ゚⊇゚)「このうち、masterとdevelopはメインブランチと呼ばれ、開発者全員で共有すべきブランチなんだ。feature、hotfix、rereaseはサポートブランチと呼ばれ、開発者がローカルで管理するブランチだ。git-flowではこれらのブランチを機能追加、バグフィクス、リリースのタイミングで使い分けるんだよ。もっと詳しく知りたかくなったら、ここを見ておくといいよ。
http://nvie.com/posts/a-successful-git-branching-model/
」
(・∠・`)乙「なるほど。各ブランチの役割がわかったわ。開発者はmaster以外にもdevelopも触っちゃダメなのね。従来のtopicブランチがその他のブランチに位置づけられるわけね。」
( ゚⊇゚)「That's right アリス。それだけでなくブランチの作成方法やマージ方法もgit flowコマンドで管理するのさ。各ブランチの役割と作成方法を以下にまとめといたから見といてくれ。各ブランチがどこから分岐して、どこにマージされるかを知っておくことが重要だよ。」
masterブランチ
リリースの状態を常に維持しているブランチ。このブランチを勝手に弄ってはだめ。
developブランチ
開発者用のブランチ。最新の開発結果を常に保持する。破棄しちゃだめ。開発者はこのブランチからローカルブランチを切って作業を行う。直接いじっちゃだめ。
作成コマンド
git flow initコマンドを実行すると作成される。
$ git flow init
featureブランチ
新しい機能を追加する時に使われるブランチ。developから分岐し、developにマージされる。マージしたタイミングで破棄される。
作成コマンド
$ git flow feature start xxx
マージ
$ git flow feature finish xxx
hotfixブランチ
不具合修正を行うのに使われるブランチ。masterから分岐し、develop、masterにマージされる。
作成コマンド
$ git flow hotfix start xxx
マージ
$ git flow hotfix finish xxx
releaseブランチ
リリースの準備を行うのに使われるブランチ。developから分岐し、masterとdevelopにマージされる。
作成コマンド
$ git flow release start xxx
$ git flow release finish xxx
機能追加が終わったら
(・∠・`)乙「作業完了。えーとコミットまでの作業は通常通りだったわね。」
$ git add --all $ git commit -m"add hello"
(・∠・`)乙「ボブ。機能追加が終わったんだけど、この後はどうすればいいのかしら?」
( ゚⊇゚)「OKアリス。まずはfeatureブランチをマージしよう。一応現在のブランチを確認してからにしてくれ。」
現在のブランチを確認
$ git flow feature * hello
マージ
$ git flow feature finish hello Switched to branch 'develop' Updating e86c07d..5ccc6e6 Fast-forward 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 helloworld.py Deleted branch feature/hello (was 5ccc6e6). Summary of actions: - The feature branch 'feature/hello' was merged into 'develop' - Feature branch 'feature/hello' has been removed - You are now on branch 'develop'
(・∠・`)乙「ボブ。マージできたわ。この後はブランチを削除すればいいのかしら?」
( ゚⊇゚)「Noアリス。git-flowでマージしたブランチは自動的に削除されるのさ。メッセージにも出てるだろ。」
$ git branch * develop master
(・∠・`)乙「本当だ。削除されてるわ。これならブランチの削除忘れも未然に防げて便利ね。私よく削除忘れるのよ(・ω<)」
リリースする
( ゚⊇゚)「よしアリス、マージが終わったら今度はreleaseブランチの作成だ」
$ 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' $ git branch develop master * release/1.0.0
( ゚⊇゚)「ブランチができたら、リリースノートを追加しよう。」
$ emacs README.md HISTORY ======= - 1.0.0: Echo "hello world"
( ゚⊇゚)「コミットしたらfinishだ。」
$ git add README.md $ git commit -m "Update README for release 1.0.0." $ git flow release finish 1.0.0 Switched to branch 'master' Merge made by recursive. README.md | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) create mode 100644 README.md create mode 100644 helloworld.py Switched to branch 'develop' Merge made by recursive. README.md | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) create mode 100644 README.md Deleted branch release/1.0.0 (was 1819ae8). 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
( ゚⊇゚)「エディタが起動したら1.0.0などを入力して閉じよう。」
(・ω・`)乙「これもdevelopにマージされるのね。この後はmasterにマージするのかしら?」
( ゚⊇゚)「その必要はないよアリス。rerease finishではmasterブランチのマージも勝手にやってくれるのさ。それだけでなくタグも打ってくれるのさ。メッセージにもでてるだろ。」
Summary of actions: - Latest objects have been fetched from 'origin' - Release branch has been merged into 'master' - The release was tagged '1.0.0' $ git tag 1.0.0
(・ω・`)乙「Greate!! なんて素敵なの。マージ、リムーブ、タグ打ちまでやってくれるなんて!」
( ゚⊇゚)「その通り。コマンド一発で複数の作業をやってくれて、さらに人為的ミスも防げるクールなツールがgit-flowだよ。さすがにリモートのpushまではしてくれないけどね。」
$ git push origin 1.0.0
( ゚⊇゚)「ところでアリス。付け鼻はやめたのかい?そっちの方が似合ってるね。」
(・ω・`)乙「べ、べつにあんたのためにやったんじゃないんだからね(///)!変換してから治すのがめんどくさいだけなんだからね!」
( ゚⊇゚)「( ´_ゝ`)フーン」
機能を追加する(まとめ)
( ゚⊇゚)「ヘイ!アリス。ボスがhelpページ追加してくれだって。機能追加の手順は覚えただろ。今度は一人でやってみな。」
(・ω・`)乙「OKボブ。まかせてちょうだい☆(ゝω・)vキャピ」
$ git flow feature start 1.1.0-help ...ゴニョゴニョ $ git commit -m"add help" $ git flow feature finish 1.1.0-help $ git flow release start 1.1.0-help ...ゴニョゴニョ $ git flow release finish 1.1.0-help $ git tag 1.0.0 1.1.0-help $ git push origin 1.1.0-help
(・ω・`)乙「ボブ。できたわよ。」
( ゚⊇゚)「乙」
git flow hotfix
( ゚⊇゚)「Hey!アリス。ボスがヘルプページがクレイジーすぎるから直してくれって言ってたぜ」
(・ω・`)乙「なんだってー!!どこが変なのかしら?」
( ゚⊇゚)「(-_-;ウーンさすがにMSDNに飛ばすのはないんじゃないかな。。。」
(・ω・`)乙「そう言われてみるとそうね。何かいい案ないかしら?」
( ゚⊇゚)「ここはやっぱりgoogle先生がクールだと思うよ。」
(・ω・`)乙「それだ!」
( ゚⊇゚)「よし!じゃ、不具合修正だ。git-flowでは不具合修正のときはhotfixブランチを使うんだよ。」
$ git flow hotfix start 1.1.1-helpfix Branches 'master' and 'origin/master' have diverged. And local branch 'master' is ahead of 'origin/master'. Switched to a new branch 'hotfix/1.1.1-helpfix' Summary of actions: - A new branch 'hotfix/1.1.1-helpfix' was created, based on 'master' - You are now on branch 'hotfix/1.1.1-helpfix' Follow-up actions: - Bump the version number now! - Start committing your hot fixes - When done, run: git flow hotfix finish '1.1.1-helpfix' $ git branch develop * hotfix/1.1.1-helpfix master
( ゚⊇゚)「修正して、finishだ」
...ゴニョゴニョ $ git flow hotfix finish 1.1.1-helpfix Branches 'master' and 'origin/master' have diverged. And local branch 'master' is ahead of 'origin/master'. Switched to branch 'master' Merge made by recursive. help.py | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) Switched to branch 'develop' Merge made by recursive. help.py | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) Deleted branch hotfix/1.1.1-helpfix (was 4666118). Summary of actions: - Latest objects have been fetched from 'origin' - Hotfix branch has been merged into 'master' - The hotfix was tagged '1.1.1-helpfix' - Hotfix branch has been back-merged into 'develop' - Hotfix branch 'hotfix/1.1.1-helpfix' has been deleted $ git tag 1.0.0 1.1.0-help 1.1.1-helpfix
(・ω・`)乙「hotfixもmasterにマージされるのね。」
( ゚⊇゚)「yes! hotfixはmasterから分岐されてmasterとdevelopにマージされるんだ。リリースブランチを作成する必要がないから直後にリリースというパターンになるから慎重にね。」
コマンドまとめ
$ git flow hotfix start 1.1.1-helpfix $ git branch develop * hotfix/1.1.1-helpfix master $ git flow hotfix finish 1.1.1-helpfix $ git tag 1.0.0 1.1.0-help 1.1.1-helpfix
作業ブランチを違うマシンでやりたいそうです
(・ω・`)乙「ねぇボブ。作業の続きを持ち帰ってやりたいんだけど、この場合はどうやるのかしら?」
( ゚⊇゚)「OKアリス。その場合はgit flow feature publishコマンドを使うんだ。そして、自宅PCではgit flow feature pullコマンドでpullするんだよ。」
会社PC
$ git flow feature publish xxx
自宅PC
$ git flow feature pull xxx
(・ω・`)乙「なるほど。feature ごにょごにょコマンドが用意されてるのね。これならPCが変わってもfinishで怒られないのね」
( ゚⊇゚)「たぶんね。怒られてもこまかいことは気にすんんな。(o^-')b グッ!」
(・ω・`)乙「・・・」
( ゚⊇゚)「・・・」
featureいじってる時にhotfixしたくなったら
(・ω・`)乙「ボブ。featureをいじってる最中なんだけど、hotfixをいじりたくなったんだけどどうすればいいのかしら?」
( ゚⊇゚)「ぐっと我慢・・(のほうがいい)」
(・ω・`)乙「・・・」
( ゚⊇゚)「・・・」
( ゚⊇゚)(・ω・`)乙
ー病院ー
(・ω・`)乙「ガチャ(ドアあける)」
( ゚⊇゚)@ベッド「クソッタレ!捨て犬の気分さ」
(・ω・`)乙「どうしたんだいボビィ?随分荒れてるじゃないか。そのケガはハニーにやられたのかい?」
( ゚⊇゚)「ぜひそうありたいもんだよ。だけど残念なことにボス公の奴さ」
(・ω・`)乙「そういえばボスがすごい形相で出て行ったわよ。何かあったの?」
( ゚⊇゚)「ボス公のフェラーリで限界に挑戦したんだ。そしたら真っ赤なフェラーリが真っ黒になっちまったよ・・・。」
(・ω・`)乙「無茶しやがって・・・(`・ω・´)ゞ。(・・・だから焦げてるのね)」
( ゚⊇゚)「そしたら、お前はクビだって。・・・(´;ω;`)ブワッ」
(・ω・`)乙「かわいそうなボブ。そのくらいでクビになるなんて・・・(´;ω;`)ブワッ」
( ゚⊇゚)「僕はプロジェクトから抜けることになったけど、きっと君ならやっていけるよね(´;ω;`)ブワッ」
(・ω・`)乙「厳しいスケジュールになるけど心配しないで。git-flowなら極めたわ。(`・ω・´)キリッ」
( ゚⊇゚)「安心したよ。僕のスケジュールは真っ白だけどね・・・(´;ω;`)ブワッ」
ー翌日ー
(・ω・`)乙「今日の作業おわり。コミットコミット」
$ svn commit -m"daily commit ☆(ゝω・)vキャピ"
参考
http://www.oreilly.co.jp/community/blog/2011/11/branch-model-with-git-flow.html
http://www.slideshare.net/monochromegane/gitflow-13940105
すぺしゃるさんくす
@Surgo
@六畳的一間