Git Flow
Gitの構成管理・運用方法として知られているGit Flowについて学びたいと思います
参考
- 『GitHub実践入門 ~Pull Requestによる開発の変革 (WEB+DB PRESS plus)』
- A successful Git branching model » nvie.com
- git-flow cheatsheet
環境
準備
git flowをサポートしてくれるツール
その名も「git−flow」(直球)をインストールします
$ brew install git-flow ==> Downloading https://homebrew.bintray.com/bottles/git-flow-0.4.1.yosemite.bot ######################################################################## 100.0% ==> Pouring git-flow-0.4.1.yosemite.bottle.tar.gz ==> Caveats Bash completion has been installed to: /usr/local/etc/bash_completion.d zsh completion has been installed to: /usr/local/share/zsh/site-functions ==> Summary 🍺 /usr/local/Cellar/git-flow/0.4.1: 15 files, 106.6K # 確認 $ git flow version 0.4.1
git-flow初期化
git-flowを使って初期化を行います
# 開発対象のリポジトリをclone $ git clone https://github.com/mktktmr/ex_git-flow.git Cloning into 'ex_git-flow'... remote: Counting objects: 6, done. remote: Compressing objects: 100% (3/3), done. remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (6/6), done. Checking connectivity... done. $ cd ex_git-flow/ # 「git flow init」でgit flowに必要な初期化を行う # オプション-d は初期設定 $ git flow init -d Using default branch names. Which branch should be used for bringing forth production releases? - master Branch name for production releases: [master] Branch name for "next release" development: [develop] $ $ git branch -a * develop master remotes/origin/HEAD -> origin/master remotes/origin/master $ $ git push -u origin develop Total 0 (delta 0), reused 0 (delta 0) To https://github.com/mktktmr/ex_git-flow.git * [new branch] develop -> develop Branch develop set up to track remote branch develop from origin.
git flowにおけるブランチの役割
master
- リリース用
- プロダクトのバージョンでtagを切る
- 各開発者はこのブランチに対してcommitすることはない
develop
- 開発用
- このブランチに開発中の最新ソースがあるよう管理する
- featureブランチ(後述)をきる元のブランチとなる
- 各開発者はこのブランチに対してcommitすることはない
feature
- 作業用
- 各開発者はこのブランチにcommitをし、作業が終わったらfeatureにPullRequestを送る
release
- バージョン番号の付与などリリースに関する作業を行う
- リリース作業中に発見されたバグはこのブランチにコミットしてよい
- 仕様変更や機能変更は行わない
- releaseブランチでの作業が完了したらmasterブランチとdevelopブランチにmergeし、masterブランチではタグを切る
hotfix
- hotfixブランチはフローにおいて必須ではなく、以下のようなことが発生した場合、適宜作成する
- release後バグが見つかり、かつdevelopブランチのソースがmergeできる状態でない
- バグや障害の対応が早急に必要で次のリリースバージョンを待つことができない
ワークフロー
featureブランチでの作業
# ブランチを最新化(1つのブランチに対して複数の開発者がいる場合) $ git pull Already up-to-date. $ # git-flowでfeatureブランチ追加 $ git flow feature start add-user Switched to a new branch 'feature/add-user' Summary of actions: - A new branch 'feature/add-user' was created, based on 'develop' - You are now on branch 'feature/add-user' Now, start committing on your feature. When done, use: git flow feature finish add-user $ # 確認 $ git branch -a develop * feature/add-user master remotes/origin/HEAD -> origin/master remotes/origin/develop remotes/origin/master $ # featureブランチをリモートにpush $ git push origin feature/add-user Total 0 (delta 0), reused 0 (delta 0) To https://github.com/mktktmr/ex_git-flow.git * [new branch] feature/add-user -> feature/add-user $ # 実装(した体で) $ touch AddUser.java $ $ git add . $ git commit -m "Add AddUser.java" [feature/add-user aae3200] Add AddUser.java 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 AddUser.java $ # pushの前にブランチを最新化 $ git pull origin feature/add-user From https://github.com/mktktmr/ex_git-flow * branch feature/add-user -> FETCH_HEAD Already up-to-date. $ # pushの前にdevelopブランチとmergeしておく(他の開発者が更新してるかもしれない) $ git merge --no-ff origin develop Already up-to-date. $ # push $ git push origin feature/add-user Counting objects: 3, done. Delta compression using up to 4 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 299 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To https://github.com/mktktmr/ex_git-flow.git 114038f..aae3200 feature/add-user -> feature/add-user # ここまできたらPull Requestを送る
デフォルトブランチについて
デフォルトブランチとは
GitHubにてリポジトリを選択した際に、最初に選択されるブランチ。
git flow ではdevelopブランチを起点にして作業をするため、git flowを採用するのなら 作業ミスを防ぐためデフォルトブランチをdevelopにすることが望ましい
デフォルトブランチの設定方法
デフォルトブランチの設定を変更したいリポジトリ開き、「setting」タブを選択
「Branches」を選択し、Default branchの項目のプルダウンからデフォルトにしたいブランチを選び、「Update」をクリックする
Pull Request後のフロー
- PRした内容をレビューをしてもらい、フィードバックをもらう
- テストが通ってない
- コーディング規約に反している
- コードが汚い
- リファクタリングの余地がある
- etc...
- レビューのフィードバックを反映させ、pushする
- 問題がなくなるまで、1〜2を繰り返す
- 管理者がdevelpブランチにマージする
Pull RequestからPR mergeまでの例
pull requestをする
フィードバックがある。。。
# フィードバックをもとに修正 $ vi AddUser.java $ git add . $ git commit -m "Done Refactoring" [feature/add-user b35e838] Done Refactoring 1 file changed, 5 insertions(+) $ # 修正内容をpush $ git push origin feature/add-user Counting objects: 3, done. Delta compression using up to 4 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 365 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To https://github.com/mktktmr/ex_git-flow.git aae3200..b35e838 feature/add-user -> feature/add-user
フィードバックが反映され、問題がなければ、pull requestがマージされる
# pull request がマージされたらローカルのdevelpブランチを更新する $ git checkout develop Switched to branch 'develop' Your branch is up-to-date with 'origin/develop'. $ git pull remote: Counting objects: 1, done. remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (1/1), done. From https://github.com/mktktmr/ex_git-flow 1e91db3..5b91113 develop -> origin/develop Updating 1e91db3..5b91113 Fast-forward AddUser.java | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 AddUser.java
以上を繰り返し機能を追加していく。
featureブランチを切る粒度については今後の研究課題。。。
releaseブランチでの作業
featureブランチによる機能開発が全て終わり、マージが済んだらリリース作業用としてreleaseブランチを切る
このブランチで行うことはバグの修正のみであり、機能追加などはしてはいけない
# ブランチの確認 $ git branch * develop feature/add-user master $ # 最新の状態にしておく $ git pull Already up-to-date. # git-flowで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 feature/add-user master * release/1.0.0 $ # バグが見つかったので、修正する(という体) $ vi AddUser.java $ git commit -am "Bugfix" [release/1.0.0 8ea7af0] Bugfix 1 file changed, 1 insertion(+) $ # git-flowでrelease 作業のクローズする # git-flow release finishを実行すると以下の処理が走る # 1. releaseブランチがmasterブランチにマージされる # 2. タグの発行 # 3. releaseブランチがdevelopブランチにマージされる $ git flow release finish Missing argument <version> usage: git flow release [list] [-v] git flow release start [-F] <version> git flow release finish [-Fsumpk] <version> git flow release publish <name> git flow release track <name> $ git flow release finish "1.0.0" Switched to branch 'master' Your branch is up-to-date with 'origin/master'. Merge made by the 'recursive' strategy. AddUser.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 AddUser.java Switched to branch 'develop' Your branch is up-to-date with 'origin/develop'. Merge made by the 'recursive' strategy. AddUser.java | 1 + 1 file changed, 1 insertion(+) Deleted branch release/1.0.0 (was 8ea7af0). 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 $ # タグの確認 $ git tag 1.0.0 $ # ブランチ確認 $ git branch * develop feature/add-user master $ # developブランチのpush $ git push origin develop Counting objects: 4, done. Delta compression using up to 4 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 434 bytes | 0 bytes/s, done. Total 4 (delta 2), reused 0 (delta 0) To https://github.com/mktktmr/ex_git-flow.git 5b91113..8f133fb develop -> develop $ # masterブランチのpush $ git checkout master Switched to branch 'master' Your branch is ahead of 'origin/master' by 5 commits. (use "git push" to publish your local commits) $ git push Counting objects: 1, done. Writing objects: 100% (1/1), 241 bytes | 0 bytes/s, done. Total 1 (delta 0), reused 0 (delta 0) To https://github.com/mktktmr/ex_git-flow.git 1e91db3..5efe88e master -> master $ # タグをpush $ git push --tag Counting objects: 1, done. Writing objects: 100% (1/1), 175 bytes | 0 bytes/s, done. Total 1 (delta 0), reused 0 (delta 0) To https://github.com/mktktmr/ex_git-flow.git * [new tag] 1.0.0 -> 1.0.0
hotfixブランチでの作業
# 1.0.0タグからhotfix/1.0.1ブランチを作成 $ git flow hotfix start '1.0.1' '1.0.0' Switched to a new branch 'hotfix/1.0.1' Summary of actions: - A new branch 'hotfix/1.0.1' was created, based on '1.0.0' - 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' # バグを修正する(体で) $ vi AddUser.java # 修正をコミット $ git commit -am "HotFix" [hotfix/1.0.1 4df2872] HotFix 1 file changed, 1 insertion(+) $ $ git push origin $ git branch develop feature/add-user * hotfix/1.0.1 master $ git push origin hotfix/1.0.1 Counting objects: 3, done. Delta compression using up to 4 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 331 bytes | 0 bytes/s, done. Total 3 (delta 1), reused 0 (delta 0) To https://github.com/mktktmr/ex_git-flow.git * [new branch] hotfix/1.0.1 -> hotfix/1.0.1
バグを修正し、hotfixブランチをpushしたらPRを送る
merge対象はmasterブランチとなることがポイント
特に問題もなく、PRが取り込まれたとする
タグの作成とリリース
タグを切ったら、hotfixとしての対応は終了だが、developブランチと差分が出て入るはずのなので、developブランチにもPRを送り、適宜mergeする
# ブランチを最新化 $ git pull remote: Counting objects: 1, done. remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 Unpacking objects: 100% (1/1), done. From https://github.com/mktktmr/ex_git-flow 8f133fb..f04db69 develop -> origin/develop * [new tag] 1.0.1 -> 1.0.1 Already up-to-date. # タグの確認 $ git tag 1.0.0 1.0.1 $ git checkout develop Switched to branch 'develop' Your branch is behind 'origin/develop' by 3 commits, and can be fast-forwarded. (use "git pull" to update your local branch) # ブランチの最新化 $ git pull origin develop From https://github.com/mktktmr/ex_git-flow * branch develop -> FETCH_HEAD Updating 8f133fb..f04db69 Fast-forward AddUser.java | 1 + 1 file changed, 1 insertion(+) # タグの確認 $ git tag 1.0.0 1.0.1