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

忘備録

日々の調べ物をまとめる。アウトプットする。基本自分用。

Git Flow

git GitHub

Gitの構成管理・運用方法として知られているGit Flowについて学びたいと思います

参考

git-model

環境

  • OS: OS X 10.10.5
  • git version 2.5.4 (Apple Git-61)

準備

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」タブを選択

f:id:mktktmr:20160212195928p:plain

「Branches」を選択し、Default branchの項目のプルダウンからデフォルトにしたいブランチを選び、「Update」をクリックする

f:id:mktktmr:20160212142146p:plain

Pull Request後のフロー

  1. PRした内容をレビューをしてもらい、フィードバックをもらう
    • テストが通ってない
    • コーディング規約に反している
    • コードが汚い
    • リファクタリングの余地がある
    • etc...
  2. レビューのフィードバックを反映させ、pushする
  3. 問題がなくなるまで、1〜2を繰り返す
  4. 管理者がdevelpブランチにマージする

Pull RequestからPR mergeまでの例

pull requestをする

f:id:mktktmr:20160212140429p:plain

フィードバックがある。。。

f:id:mktktmr:20160212140740p:plain

# フィードバックをもとに修正
$ 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がマージされる

f:id:mktktmr:20160212141344p:plain

# 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ブランチとなることがポイント

f:id:mktktmr:20160215203322p:plain

特に問題もなく、PRが取り込まれたとする

f:id:mktktmr:20160215203649p:plain

タグの作成とリリース

f:id:mktktmr:20160215211739p:plain

f:id:mktktmr:20160215211749p:plain

f:id:mktktmr:20160215211821p:plain

f:id:mktktmr:20160215213627p:plain

タグを切ったら、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