初心者向け、いろいろ細かく説明した、Git Flowに沿った運用方法について

git flow に沿った運用は概念は分かっていても、具体的にどうやって運用を行えばいいのか色々と調べている内に手順が出来たので、せっかくなので記事にしてみようと思いました。　初学者の方は参考にして頂ければ幸いです。

https://nvie.com/posts/a-successful-git-branching-model/


#### 各ブランチの役割
* masterブランチ：本番環境
* releaseブランチ：ステージングとしての役割や、本番環境に近い状態でデプロイを行う環境
* hotfixブランチ：緊急の修正作業用
* developブランチ：開発用
* featureブランチ：作業用
※開発環境は決まってはいませんので、プライマリブランチ（main, develop）、サポートブランチ（release, feature, hotfix）というくらいの感覚でも良いかと思います。

## 1.　準備作業

* プロジェクトが手元にないなら、まずはcloneコマンドでコピーします。
```
git clone ＜cloneしたいGitHubプロジェクトのURL＞
```

#### 1-1.　featureブランチの作成

```
% git branch  # ブランチの確認
* develop  # developブランチにいることを確認
  main
% git branch feature/v1.0.0.0/DM　　# developブランチから、featureブランチを作成
```
この時、リリースしているバージョンの番号があれば、記載します。今回は「v1.0.0.0」としてみます。　そして、今回はDM機能を作成するために、作業用のfeatureブランチを作成するという想定にしたので、「DM」にしています。
※featureブランチの命名規則については、今回下記のように考えてみましたが、いろいろな表記があるので、下記の記事を参考にお好きな命名規則を考えてみるといいと思います。
feature/[派生元バージョン番号]/[機能名]
(例)feature/v1.0.0.0/DM
参考：[バージョンにあれこれ考えを巡らせてみる](https://qiita.com/t_nakayama0714/items/c312bc5edcce6c214856)


#### 1-2.　featureブランチを作成したら、実際に作業を行うfeatureブランチへ切替
```
% git switch feature/v1.0.0.0/DM
```

## 2.　開発作業

* 作業を行う、featureブランチに切り替えたら、実際にコードを書いて機能を作成していきましょう。
<details><summary><font color="Teal">熱中してコミットを忘れないように（表示する）</font></summary>
ある機能を作りたいという時に、例えばDM機能を作るといっても、多くのファイルにコードを書くことになります。初心者の方であれば、コードを書いたけど元に戻すなんてこともよくあると思います。　そういう時のために、コミットはマメにしておくことをお勧めします。　ゲームのセーブ見たいなもので、後で見直したり、戻したりする際に細かくコミットしておくと、エラーの切り分けにもなったりするので、細かくコミットすることを心がると良いと思います。
</details>
<details><summary><font color="Teal">(例)コミットの例（表示する）</font></summary>
(例)下記のようにルーティングの設定を書いたら、コミットするといったイメージでも良いかと思います。
※ちなみに、「-m」のオプションはコミットと同時にコミット名も設定できるオプションで、コミット名は” ”で囲ってあげましょう。　それと、「#10」と記載していますが、これはGitHubのIssuesの管理番号をコミット名に記載することで、Issuesの管理に紐づけることができます。これもお勧めなので、「DM機能の作成 ＃10」見たいなIssuesを作成したとしたら、下記のようにコミット名に記載しておきましょう。

```
% git commit -m "ルーティングの設定 #10"
```

</details>

## 3.　マージ手順（develop ← feature）

featureブランチで作業を行い、あるまとまった機能ができたタイミングで、developブランチにマージを行います。

<details><summary><font color="Teal">マージのタイミングについて（表示する）</font></summary>
規模やペースはプロジェクトによってまちまちですが、期間としては1週間でも違和感はないようです。　 例えば開発手法がアジャイルのように速いサイクルであれば早くなるでしょうし、またマージはコードレビューとセットで行うことが多いので、マージしたくてもできないかもしれません。 特例も起こるようで、よくあるのはフロントエンドとバックエンドが同時に開発を進めたときに、フロントエンドはバックエンドのある機能ができていないと実装がやりづらいという状況で、バックエンドは簡単なモック（擬似）を先にマージする、というパターンがあるようです。 運用としてもdevelopにマージした時点でCI/CDでテストを動かす、というのもよくとられている構成だと思いますが、あまりたくさん動かすとコストがかかるので節約も考えないといけないようです。
</details>

#### 3-1.　今作業しているローカルブランチが、featureブランチであることを確認

```
% git branch
  develop
* feature/v1.0.0.0/DM
```

#### 3-2.　GitHubにある差分をローカルのfeatureブランチに取り込む

```
% git pull origin feature
```
※git pull origin feature とは、fetch と merge origin/feature をくっ付けたもの
参考：[git pull と git pull –rebase の違いって？](https://kray.jp/blog/git-pull-rebase/)
* git fetch：リモートの各ブランチの状態をリモート追跡ブランチにコピー
* git merge origin/feature：リモート追跡ブランチの状態をローカルにマージさせfeatureブランチを最新の状態にする。


#### 3-3.　プルリクエストを作成し、developブランチにマージ

GitHub上で、プルリクエストを作成して、どんな内容を変更したか、コメントを記載しましょう。チーム開発の場合はリーダーなど実装者と異なる方がプルリクエストの承認（マージ）されるケースも多いようです。
会社では、チームの担当するメンバー全員でコードレビューを行い、全員の承認が出たらマージするといったケースがほとんどのようですが、個人開発でもプルリクエストを作成して、コメントを残す方が良いと思いますので、習慣化することをお勧めします。

プルリクエストについては、次の記事を参考にすると勉強になると思います。
参考：[チーム開発におけるプルリクの作法](https://qiita.com/ikuwow/items/fb52a54c086398eb5b92)


## 4.　マージ手順（release← develop）

1つ機能ができたら、リリースするため、developブランチをreleaseブランチにマージしていきます。

</details>

#### 4-1.　1の手順と同様に、developブランチで、pullを実行

```
% git branch
* develop
  feature/v1.0.0.0/DM
% git pull origin develop　　# ローカルを最新化しましょう。
```
#### 4-2.　プルリクエストを作成し、relaseブランチにマージ

#### 4-3.　featureブランチはrelaseブランチにdevelopブランチをマージした時点で削除

* 削除はローカルとリモートの両方を削除しましょう。
```
% git branch  # ブランチの確認
  develop
* feature/v1.0.0.0/DM
% git switch develop  # featureブランチ以外に切り替えましょう。
% git branch -dr origin/feature/v1.0.0.0/DM  # リモートブランチの削除
% git branch -D feature/v1.0.0.0/DM  # ローカルブランチの削除
```

## 5.　releaseブランチでの作業

* リリースした際に不具合があれば、releaseブランチ上で修正を行いましょう。

## 6.　マージ手順（main ← release）

本番環境へリリースするため、releaseブランチをmainブランチにマージする作業を行います。

#### 6-1.　バージョン番号を付ける
プルリクエストを作成する際に、リリースするバージョン番号を付けましょう。
ちなみに、バージョン番号の形式は「Major番号.Minor番号.Patch番号」と、3つの数字をドットでつないだ番号がメジャーで、「セマンティックバージョニング」という考え方があります。
例：1.0.0

Patch番号：バグ修正の時にインクリメントする番号
Minor番号：後方互換性がある変更の時にインクリメントする番号
Major番号：後方互換性がない変更の時にインクリメントする番号

#### 6-2.　プルリクエストを作成し、mainブランチにマージ

※mainブランチでは作業せず、唯一コミットは作成しません。

#### 6-3.　タグを付ける

タグは、「コミットを参照しやすくするために、わかりやすい名前を付けるもの」という概念です。
タグはgemを作成しているわけではない限り、あまり使用する機会がないかと思われますが、主にそのライブラリを使用するユーザーに向けてのものになります。
従って、変更のないmainブランチにつけるのが理想的かと思われます。
逆にmainブランチ以外ではタグは使用しないようです。（mainにマージされるというのもありますが）
ちなみに、GitHubの場合はtag付けするとその時点でのソースをzipなどでダウンロードできるようになります。

実際にタグを付ける際は、GitHub Desktop上で、タグを付ける方法が、わかりやすく簡単でオススメです。
オススメ：[GitHub Desktop](https://desktop.github.com/)


## 7.　mainブランチでバグが発生した場合

####  7-1.　mainブランチからhotfixブランチを作成

```
% git branch  # ブランチの確認
  develop
* main
% git branch hotfix  # hotfixブランチの作成
```

* hotfixブランチを作成したら、実際に作業を行うhotfixブランチへ切替
```
% git branch  # hotfixブランチが出来ていることを確認
  develop
* main
  hotfix
% git switch hotfix  # hotfixブランチへ切り替え
% git branch
  develop
  main
* hotfix  # hotfixブランチに切り替わっていることが確認出来ました
```


####  7-2.　hotfixブランチでバグの修正を行い、mainにマージ（プルリクエスト）

注意点としては、hotfixブランチで、バグの修正を行なっている間は、新たにreleaseブランチからmainブランチへマージした場合、バグが直ったとしても、どちらの影響か切り分けるのが手間なので、hotfixブランチで作業している間は、新たにmainブランチへマージするといったことは普通はしないようです。

####  7-3.　hotfixブランチの内容をreleaseブランチとdevelopブランチに取り込む

hotfixブランチでバグの修正と、mainブランチへのマージが終われば、releaseブランチとdevelopブランチに差分をマージして最新化しましょう。
* release ← hotfix へマージ
```
% git switch release  # releaseブランチへ切り替え
% git branch  # releaseブランチに切り替わっていることを確認
  develop
* release
  hotfix
* git merge hotfix  # release ← hotfix へマージ
```
* develop ← hotfix へマージ
```
% git switch develop  # developブランチへ切り替え
% git branch  #developブランチに切り替わっていることを確認
* develop
  release
  hotfix
* git merge hotfix  # develop ← hotfix へマージ
```

#### GitHubを使用したプルリクエストと、コマンドを使用したマージについて

プルリクエストは今作業しているブランチから見て、本番環境に近いブランチへマージする際に、問題が無いかレビューを行う為のものなので、今作業しているブランチから見て開発環境側へマージする際は、プルリクエストではなく、コマンドでマージでも良いとい思います。（レビュー対象が被ってしまうため）


#### 以降は、 "1-1." の手順に戻って、この繰り返しになります。


## 最後に
Git Flowをしっかり自分の中に落とし込んだことで、GitHubについての理解も深めることが出来ました。また、実際の現場ではどのように作業をされているのか、知る機会にもなりましたので、学びは多かったです。　最初は全く分かりませんでしたが、先人の方々の記事に助けられましたので、私の記事も初学者の役に立てばいいかなと思います。

最後までお読み頂きありがとうございました。