gitの運用ワークフローのメモ（git-flow、github flow等）

# 前置き
複数人での開発や自社サービス運用などを視野に入れる場合に
安全なサービス提供の為の選択肢として概念や運用フロー例を調べたり経験したものを社内用にまとめた時のメモです。

※結構前に作成して放置してたので引用元がわからなくなってる箇所が多々あります。

# gitとは
> Git（ギット[2][3][4]）は、プログラムのソースコードなどの変更履歴を記録・追跡するための分散型バージョン管理システムである。Linuxカーネルのソースコード管理に用いるためにリーナス・トーバルズによって開発され、それ以降ほかの多くのプロジェクトで採用されている。Linuxカーネルのような巨大プロジェクトにも対応できるように、動作速度に重点が置かれている。現在のメンテナンスは濱野純 (Junio C Hamano) が担当している。
Gitでは、各ユーザのワーキングディレクトリに、全履歴を含んだリポジトリの完全な複製が作られる。したがって、ネットワークにアクセスできないなどの理由で中心リポジトリにアクセスできない環境でも、履歴の調査や変更の記録といったほとんどの作業を行うことができる。これが「分散型」と呼ばれる理由である。
[wikipedia](https://ja.wikipedia.org/wiki/Git)

[サルでもわかるGit入門](http://www.backlog.jp/git-guide/)
[SourceTree：Git Flowを試してみました](http://tyoshikawa1106.hatenablog.com/entry/2016/05/19/150728)
※gitはコマンドが複雑なのでSourceTreeなどのクライアントで視覚的にやると理解しやすいです。
※Visual Studio Codeならgitもコンソールも一画面でできますよ！（VSC布教）

## gitとSVNについて
### SVNとは
> Apache Subversion（アパッチ・サブバージョン; SVN）はプログラムのソースコードなどを管理する集中型バージョン管理システムの一つ。
[wikipedia](https://ja.wikipedia.org/wiki/Apache_Subversion)

### gitとSVNを比較（git推しの主観混じり）
- SVNはコミットが即時にプロジェクトに共有されるのでlogを見ても他の開発者と作業が混ざり混乱を招くことがあり、前のバージョンに戻す際に最新の注意が必要

- SVNはチーム単位での成果しか管理出来ないが、Gitは開発者個別の作業をバージョン管理できる

- gitはローカルにクローンしてきたものの範囲内でオフラインで勝手気ままに作業でき、マージ前にPullRequestでコードのダブルチェックなどして慎重なリリースができる

- SVNはgitでいうmaster一本でブランチ無しで作業しているようなものなので、複数人が常に更新する場合、いつでも本番相当（リリース可能な）環境を用意できるわけではなく不安定

### おおざっぱな用語解説
- リポジトリ
    - 履歴管理を行う場所
- ローカルリポジトリ
    - リモートリポジトリからクローンしてきた自分のPC内のリポジトリ
- リモートリポジトリ
    - git管理してるサーバー上のリポジトリ
- コミット
    - 変更対象をローカルリポジトリに反映すること
- プッシュ
    - ローカルリポジトリの変更をリモートリポジトリに反映させること
- プル
    - リモートリポジトリの変更をローカルリポジトリに反映させること
- フェッチ
    - リモートリポジトリの変更が無いか更新して確かめること。あればプルする
- マージ
    - 異なるブランチの変更を反映させること
- コンフリクト
    - マージ対象のファイルで個別作業をした同じファイルが変更されており、マージができないこと（手動で解消してからマージ）
- ブランチ
    - 枝分かれさせて作った作業スペースみたいなこと
- タグ
    - 履歴管理上の重要なポイントに印をつける。これをバージョン番号として管理したりする


# gitの代表的な運用ワークフローについて
github flowはgit-flowを簡略化したもの
GitLab flowは後発（勉強しときます）
これらの運用ワークフローからチームにとって最適なルールを決めて運用していく

## git-flow

![git-flow概念](https://qiita-image-store.s3.amazonaws.com/0/166550/e578a4b2-b287-2d14-e5bc-ff2ecf1e531f.png)

[A successful Git branching model](http://nvie.com/posts/a-successful-git-branching-model/)

## git-flow運用について
学習コストは慣れるまで少し煩雑に感じるかもですが、慣れると安心して運営ができます。
### ブランチについて
#### メインブランチ
・masterブランチ（その名の通りマスターとして最新のリリースの状態を保持する。このブランチで作業するのダメ絶対）
・developブランチ（レポジトリ作成したらmasterブランチから枝分かれさせる。開発ブランチ。マスターの1歩手前。基本的にここで作業はしない）

#### 作業ブランチ
- featureブランチ（developブランチから枝分かれさせる。機能追加など。規模が大きくなる場合は親fearuteブランチをきってから関連する子のブランチを作る。）
    - ブランチ名ルールの例 : feature/○○○（チケット管理があればチケット名）-△△（追加する機能の名前や修正内容）、さらに複数名作業する場合はfeature/○○○-△△を親ブランチとしてfeature/○○○-△△-□□（△△の中のなにをするのかとか）を作り作業してfeature/○○○-△△にマージ。
- releaseブランチ（developブランチから枝分かれさせる。リリースするブランチ。タグ（バージョン番号など緊急時に戻すところがわかるもの）をつけてリリース完了したらmasterとdevelopにマージする）
    - ブランチ名ルール例 : release/○○○（リリースバージョンやリリース日）
- hotfixブランチ（masterブランチから枝分かれさせる。緊急修正用のブランチ。通常のリリーススケジュールから漏れた緊急の修正はここでおこなう。タグ（バージョン番号）をつけてリリース完了したらmasterとdevelopにマージする）
    - ブランチ名ルール例 : hotfix/○○○（現在のリリースバージョンなど）-△△（修正内容など、どこどこの-bugFixとか）

### 開発手順例
#### 通常編
1.developからfeatureブランチを切る
2.featureブランチまたはfeatureブランチの子ブランチで作業
3.作業完了及びデバッグ完了したら親ブランチ(枝元のブランチ)にプルリクエストを出す
4.コードレビューが終わったら修正などして確認者にマージ及びfeatureブランチの削除をしてもらう
5.リリース当日はdevelopからreleaseブランチを切って、万が一修正があればreleaseブランチから修正ブランチを作って作業し、releaseブランチに向けてプルリクエストを出してマージしてもらう
6.releaseブランチをmasterとdevelopにマージする。masterにタグ(リリース管理するバージョンや名前)付けをしてリリース（jenkinsなどのciツールなどを使用してデプロイする場合はタグでビルドする）。
※releaseブランチは念のために次のリリースまで残したりする（なにかあったときに戻せるよに）。問題なければリリース作業者が削除
7.プロジェクト管理をしている場合はチケットを本番反映済みにする

#### 緊急不具合対応編
1.masterからhotfixブランチを切ってそこからfeatureブランチを作成
2.featureブランチで作業完了及びデバッグ完了したらhotfixブランチにプルリクエストを出しレビュアーにマージしてもらう
3.hotfixブランチをmasterとdevelopにマージする
4.masterブランチにタグ(リリース管理するバージョンや名前)付けをしてmasterとdevelopにマージしてリリース（jenkinsなどのciツールなどを使用してデプロイする場合はタグでビルドする）。
※hotfixブランチは念のために次のリリースまで残してたりする。問題なければhotfixブランチ作業者が削除



## github flow

![github flow概念](https://qiita-image-store.s3.amazonaws.com/0/166550/5fd0e9a2-6ae3-8c18-404a-2eeaf8fd1b22.png)

### 基本原則
- masterブランチは、常時デプロイ可能である
- 機能追加、バグフィックスなどは 説明的な名前のブランチをmasterから作成する
- 作成したブランチでローカル開発。小さい単位でこまめにコミットし、リモートにもこまめにPush
- フィードバックや助言が欲しい時、ブランチをマージしてもよいと思ったときは、Pull Requestを作成する
- フィードバックや助言が欲しい時に作成するPull RequestをWIP Pull RequestといいPull Request名の頭に [WIP] をつけるのが慣習
- レビューがOKを出してもらったら、masterへマージ
- masterへpushしたら、即デプロイをする

[Scott Chacon on the Interwebs](http://scottchacon.com/2011/08/31/github-flow.html)
## github flow運用について

### ブランチについて
#### メインブランチ
・masterブランチ（その名の通りマスターとして最新のリリースの状態を保持する。このブランチで作業するのダメ絶対）

#### 作業ブランチ
- featureブランチ（masterブランチから枝分かれさせる。機能追加など。規模が大きくなる場合は親fearuteブランチをきってから関連する子のブランチを作る。）
    - ブランチ名ルール例 : feature/○○○（チケット管理があればチケット名）-△△（追加する機能の名前や修正内容）、さらに複数名作業する場合はfeature/○○○-△△を親ブランチとしてfeature/○○○-△△-□□（△△の中のなにをするのかとか）を作り作業してfeature/○○○-△△にマージ。
- hotfixブランチ（masterブランチから枝分かれさせる。緊急修正用のブランチ。通常のリリーススケジュールから漏れた緊急の修正はここでおこなう。タグ（バージョン番号）をつけてリリース完了したらmasterとdevelopにマージする）
    - ブランチ名ルール例 : hotfix/○○○（現在のリリースバージョン）-△△（修正内容など、どこどこの-bugFixとか）

### 開発手順例（git-flowの簡易形）
#### 通常編
1.masterからfeatureブランチを切る
2.featureブランチまたはfeatureブランチの子ブランチで作業
3.作業完了及びデバッグ完了したら親ブランチ(枝元のブランチ)にプルリクエストを出す
4.コードレビューが終わったら修正などして確認者にマージ及びfeatureブランチの削除をしてもらい、すぐにmasterをリリースできる
5.プロジェクト管理をしている場合はチケットを本番反映済みにする

#### 緊急不具合対応編
1.masterからhotfixブランチを切ってそこからfeatureブランチを作成
2.featureブランチで作業完了及びデバッグ完了したらhotfixブランチにプルリクエストを出しレビュアーにマージしてもらう
3.hotfixブランチをmasterにマージしてmasterブランチをリリース

## GitLab flow（おまけ）
GitHub flow + リリースに必要なブランチみたいな感じ？
きちんと理解できてないので勉強しておきますm(_ _)m


#### productionブランチ
![productionブランチ](https://qiita-image-store.s3.amazonaws.com/0/166550/cd40ce75-70f9-a8d0-25e9-b5e890d4ee66.png)


#### 環境ブランチ

![環境ブランチ](https://qiita-image-store.s3.amazonaws.com/0/166550/caab4529-2a7b-216a-90b0-a1cef7f56be1.png)

#### releaseブランチ
![releaseブランチ](https://qiita-image-store.s3.amazonaws.com/0/166550/eca3a438-6dcf-8649-5131-e3084b65423f.png)


[GitLab Flow by Sytse Sijbrandij (GitLab)](https://about.gitlab.com/2014/09/29/gitlab-flow/)