Git操作とブランチ戦略

# ブランチ戦略の種類
代表的なブランチ戦略を紹介。
## Git-Flow
アプリケーションなど、リリースを必要とする開発に適したブランチ戦略。
登場するブランチは以下の5つ。

| ブランチ名 | 用途 | 作成タイミング | 削除タイミング |
|:-|:-|:-|:-|
| master | 最新の資材を管理するブランチ | 開発開始時 | 永続させるため、削除しない |
| develop | 開発を行うためのブランチ | 開発開始時 | 永続させるため、削除しない |
| feature | 機能追加を行うためのブランチ | 機能追加開始時 | 機能追加が完了し、developブランチにマージした後 |
| release | リリースを行うためのブランチ | リリース時 | リリースが完了し、masterブランチとdevelopブランチにマージした後 |
| hotfix | リリース後に、緊急のバグ修正を行うためのブランチ | バグ修正開始時 | バグ修正が完了し、masterブランチとdevelopブランチにマージした後 |

運用の流れ

![Git-Flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367074/4b0c02d6-33e5-cdf2-4c05-d9ce8fbea7aa.png)

## GitLab-Flow
GitLabにおける開発に適したブランチ戦略。
登場するブランチは以下の4つ。

| ブランチ名 | 用途 | 作成タイミング | 削除タイミング |
|:-|:-|:-|:-|
| master | 最新の資材を管理するブランチ<br>開発環境へのリリースを行うためのブランチ | 開発開始時 | 永続させるため、削除しない |
| feature | 機能追加を行うためのブランチ | 機能追加を行う時 | 機能追加が完了し、masterブランチにマージした後 |
| pre-production | ステージング環境へのリリースを行うためのブランチ | 初めてステージング環境へリリースを行う時 | 永続させるため、削除しない |
| production | 本番環境へのリリースを行うためのブランチ | 初めて本番環境へリリースを行う時 | 永続させるため、削除しない |

運用の流れ

![GitLab-Flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367074/6cd9e93e-9fdb-11fa-63b6-4ef3f1f53ff3.png)

## GitHub-Flow
GitHubにおける開発に適したブランチ戦略。
非常にシンプルな構成になっており、1日に複数回リリースを行う開発に適している。
登場するブランチは以下の2つ。

| ブランチ名 | 用途 | 作成タイミング | 削除タイミング |
|:-|:-|:-|:-|
| master | 最新の資材を管理するブランチ<br>リリースを行うためのブランチ | 開発開始時 | 永続させるため、削除しない |
| feature | 機能追加を行うためのブランチ | 機能追加を行う時 | 機能追加が完了し、masterブランチにマージした後 |

運用の流れ

![GitHub-Flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367074/f5a530f4-7bc3-fcef-5abe-607a8c4f8c6d.png)

GitHub-Flowでは、以下の6つのルールを順守する必要がある。

 1. masterブランチは常にデプロイ可能である。
 1. masterブランチからfeatureブランチを作成する。
 1. featureブランチを定期的にプッシュする。
 1. プルリクエストを活用する。
 1. プルリクエストが承認されたらmasterへマージする。
 1. masterブランチへのマージが完了したら直ちにリリースを行う。
 
# 基本的なGit操作
## clone
Gitで管理している資材を取得する。

```
git clone {リポジトリのURL}
cd {クローンしたローカルリポジトリのディレクトリ}
```

## branch
クローンしたリポジトリに存在するブランチの一覧を出力する。

```
git branch -a
```

## checkout
クローンしたローカルリポジトリで、ブランチを切り替える。
または、ブランチを新しく作成する。

* 既に存在するブランチに切り替える場合

```
git checkout {切り替えたいブランチ名}
```

* 新しくブランチを作成する場合

```
git checkout -b {切り替えたいブランチ名}
```

## commit / push
資材に加えた変更を記録し、リモートリポジトリに反映する。

```
git add {変更を加えたファイルパス} 
git commit -m "コミットメッセージ"
git push origin {ブランチ名}
```

`git add`コマンドで、カレントディレクトリ配下の階層にある変更を加えたファイルを一括で指定する場合は、

```
git add .
```

とする。

## コミットの取り消し
コミットした内容を取り消すには、2種類の方法がある。

### revert
`git revert`コマンドは、指定したコミットを打ち消す変更を自動で加えてくれる。
あくまでも指定したコミットを打ち消す変更を加えるだけで、指定したコミットよりも前の状態に戻してくれる（指定したコミットを完全になかったことにしてくれる）わけではないため、注意。
また、場合によってはコンフリクトが発生することがあるため、そちらも注意。

```
git revert {取り消したいコミットのID}
```

上記のコマンドを実行すると、エディタが開きコミットメッセージの編集を求められる。
コミットメッセージの編集を飛ばしたい場合は、

```
git revert {取り消したいコミットのID} --no-edit
```

とすること。

取り消したいコミットが複数ある場合は、

```
git revert HEAD...HEAD~{取り消したいコミットの数} --no-edit
```
とすると、最新のコミットから指定した数までのコミットを一気に取り消すことができる。

マージコミットを取り消す場合は、以下の通り。

```
git revert -m {1または2} {取り消したいマージコミットのID} 
```
:::note info
-mオプションには、マージ先とマージ元のどちらの状態を保持するかを1または2の数値で指定する。
1がマージ先、2がマージ元である。
たとえば、
feature/add-functionブランチ ⇒ masterブランチ（矢印はマージの向き）
というマージコミットを取り消す場合、-mオプションに1を指定するとmasterブランチ、2を指定するとfeature/add-functionブランチの状態を保持する。
:::

### reset
ここでは`--hard`オプションを指定する場合のみ取り上げる。
`git reset --hard`コマンドは指定したコミットの状態に戻してくれる。
`git revert`コマンドとは違い、資材を指定したコミットの状態に強制的に戻すため、それ以降のコミットは履歴や作業ツリーからも削除される。

```
git reset --hard {戻したいコミットのID}
```

ここでは`--hard`オプションのみ取り上げたが、他にも`--soft`オプションや`--mixed`オプションが存在するため、詳しく知りたい方は以下を参照。
https://www-creators.com/archives/1069