【GitHub】GitHub Flowの運用手順について

#はじめに

[【GitHub】ブランチの運用方法について](https://qiita.com/Kai_82/items/d98c61e0faa67f417829)で
GitHub Flowについて軽く紹介していますので、ぜひそちらもご覧ください。

この記事は独学で学習中の筆者がGitHub Flowについて学習してみて、
一連の操作（またはコマンド）を紹介している記事になります。
ツッコミどことがあるかもしれませんがその際は教えていただけますと幸いです。

この記事は、GitHubは使ったことがあるが
しっかりとした運用方法で使ったことはないという方におすすめだと思います。

#GitHub Flow

GitHub Flowは、ブランチの有名な運用方法の中の一つです。

ブランチとは、履歴の流れを分岐して記録していくためのものです。
分岐したブランチは他のブランチの影響を受けないため、同じリポジトリ中で複数の変更を同時に進めていくことができます。

また、分岐したブランチは合流させることもでき、それを**マージ**と言います。

GitHubではリポジトリ作成時にmasterというブランチが自動作成されるのですが、
GitHub Flowではmasterブランチを**常時デプロイが可能であるブランチ**とします。

常時デプロイが可能であるとはどのような状態かというと、
**常に安定しているブランチで、リリース可能な状態であるということ**ということです。

機能の追加やバグ修正を行いたい場合にmasterブランチをいじってしまうと、
「常時デプロイが可能である」というルールを破ってしまうことになるので、
作業用のブランチを作成してそちらで作業をおこないます。

作業終了後にmasterブランチにマージしデプロイするという流れです。

次にGitHub Flowのルールですが、下記のようなルールがあります。
(全人類共通かわかりませんが私の認識ではこんな感じです。)

**1. masterブランチは、常時デプロイ可能な状態を保つ
2. 全てのブランチはmasterブランチから作成する
3. 作業内容が分かるようなブランチ名をつける
4. 作業中のブランチは定期的にプッシュする
5. Githubのプルリクエストを利用してレビューを行なってから、masterブランチにマージする
6. マージされたmasterブランチのコードはすぐにデプロイする
7. デプロイ後は速やかに作業していたブランチを削除する**

文章だけだとわかりにくいと思いますので、実際に運用してみようと思います。

##運用手順

まずはじめに、リポジトリを作成します。
自分のGitHubのページから右上の`＋`をクリックし、`New repository`を選択します。
![スクリーンショット 2021-02-20 12.20.48.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/132a3c7b-6719-dba3-7fa6-5b33b0516ccf.jpeg)
リポジトリ作成画面に来たら、リポジトリの名前を入力し、`Create repository`をクリックします。
![スクリーンショット 2021-02-20 12.25.19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/7d26589f-54a3-9704-096a-8165d965cbc0.jpeg)
今回は練習なのでAdd a README fileにチェックは付けていません。

READMEファイルとは、説明書的なものなので必要な方は付けてください！

作成すると次のような画面になると思いますので、
四角で囲んでいる箇所をSSHにし、右に記載されているgit@から始まるURLをコピーしておいてください。
![スクリーンショット 2021-02-20 12.32.01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/78285363-2252-71ce-efd0-f773c22ba8d3.jpeg)

次にターミナルを起動します。
`command + スペースキー`で検索フィールドを出し`ターミナル`と入力しEnterを押します。

ターミナルが開かれるわけですが、ここから少し操作していきます。
今回はデスクトップ上にtestディレクトリを作成し、そちらにcloneを作成します。

下のコマンドを順に打っていけば作業を進められますが、
なんとなくでいいので理解しながら進めた方がいいかもしれません。

**ディレクトリ作成**

```
$ mkdir test   
```
**作成したディレクトリに移動**

```
$ cd test/   
```
**作成したリポジトリのcloneを作成**(######は人によって異なります)

```
$ git clone git@github.com:######/github-flow.git
```
**クローンで複製したgithub-flowに移動**

```
$ cd github-flow/   
```
**sampleFileを作成します**

```
$ touch sampleFile    
```
**sampleFileを編集し適当にテキストを入力**
viでの編集がよくわからない方は、普通にデスクトップから操作してファイルを作成してください。

内容はなんでもいいですが、私はtest1にしました。

```
$ vi sampleFile    
```
**作成したファイルをaddする**
addすることにより、バージョン管理の対象としてsampleFileを追加することができます。

```
$ git add sampleFile    
```
gitの状態を確認してみます。
一番下の`new file:   sampleFile`から
先ほど作成したファイルがステージ領域（コミット前の一時領域）に追加されていることがわかります。

```
$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
	new file:   sampleFile
```

**コミットの実施**
`git commit`だけでもコミットすることはできますが、コメント画面などを省略するために下記のように実施しました。

```
git commit -m "1回目のコミットです。"
```

**ログの確認**
ログを確認するとコミットされていることがわかります。

```
$ git log
commit f4e4a23f609481a8a1f4a2bbf21b9f121684 (HEAD -> master)
Author: Onishi Ryosuke <onishi.apppppppp@gmail.com>
Date:   Sat Feb 20 12:41:39 2021 +0900

    1回目のコミットです。
```
**リモートリポジトリへ送信**
コミットした内容を送信します。

```
$ git push
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 261 bytes | 261.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:onishi-app/github-flow.git
 * [new branch]      master -> master
```

最初に作成したリポジトリの画面にいきページの更新をおこないます。
すると次のような画面になっていると思います。
![スクリーンショット 2021-02-20 13.07.52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/1dbb0f2a-c924-ba89-34b8-70463444df15.jpeg)

sampleFileがgithub-flowリポジトリに存在しており、
コミットの時のコメントが振られています。

sampleFileをクリックすると画面が移動し、
sampleFileの中身の内容を表示してくれます。
![スクリーンショット 2021-02-20 13.09.04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/8666036d-dd97-6f3e-8c8c-821d5457f754.jpeg)



では、今のmasterブランチの状態がデプロイ可能な状態であると仮定してGitHub Flowの運用を行っていきたいと思います。
現在のmasterブランチには`sampleFile`が作成されており中身には`test1`と記載されている状態です。

今回は、「sampleFileにtest2という文字を追記する」という作業を行う流れをGitHub Flowで行っていきます。

おさらいですが、GitHub Flowのルールは下記のような内容です。

1. masterブランチは、常時デプロイ可能な状態を保つ
2. 全てのブランチはmasterブランチから作成する
3. 作業内容が分かるようなブランチ名をつける
4. 作業中のブランチは定期的にプッシュする
5. Githubのプルリクエストを利用してレビューを行なってから、masterブランチにマージする
6. マージされたmasterブランチのコードはすぐにデプロイする
7. デプロイ後は速やかに作業していたブランチを削除する

`1. masterブランチは、常時デプロイ可能な状態を保つ`に関しては
現在のsampleFileがデプロイ可能な状態であると仮定して進めていきます。

##ブランチの作成

次に、`2. 全てのブランチはmasterブランチから作成する`をおこないます。

###ターミナルの場合 

ブランチの作成
`git branch <branch名>`

今回は、feature-add-test2という名前のブランチを作成しました。
※masterブランチから実施しないとmasterブランチからの分岐になりません。

```
$ git branch feature-add-test2
```

ブランチが作成されているか確認

現在存在するブランチの一覧が表示されます。
現在は、masterブランチと先ほど作成したブランチが表示されるはずです。

また、`*`がついている方が現在操作しているブランチになります。

```
$ git branch
  feature-add-test2
* master
```


###ブラウザの場合
赤枠のmasterをクリックします。
![スクリーンショット 2021-02-20 13.23.17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/dc4034a3-cb3c-1755-5eca-deed6ecf7b70.jpeg)
検索フィールドが表示されますが、ここに作成したいブランチの名前を入力します。
ブランチが存在しない場合は`Create branch:ブランチ名 from "master"`と表示されますので、
そこをクリックするとmasterブランチから分岐したブランチを作成することができます。
![スクリーンショット 2021-02-20 13.23.23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/4aef0781-5eef-2537-d7fa-b04d218326ec.jpeg)

ここまででブランチが作成できたと思います。

###作業ブランチの変更

では、次にブランチの移動を行いたいと思います。

現在いるブランチはmasterだと思います。
masterブランチは常にデプロイ可能な状態である必要があるので
masterブランチのファイルを編集してしまうと編集中はデプロイが可能な状態ではなくなってしまいます。

なので、masterブランチと同じ状態であるfeature-add-test2ブランチを修正し修正内容をmasterブランチにマージします。

###ターミナルの場合
先ほど作成したブランチに移動するためにcheckoutコマンドを使用します。

```
$ git checkout feature-add-test2
```

###ブラウザの場合

リモートリポジトリの最新の状態をローカルリポジトリに取得します。

**リモートリポジトリ**
-> 「リモートにある」つまり元となるリポジトリになります。

**ローカルリポジトリ**
-> 「ローカルにある」つまり自分の手元（PC）にあるリモートリポジトリから複製したリポジトリになります。

```
$ git pull
From github.com:onishi-app/github-flow
 * [new branch]      feature-add-test2 -> origin/feature-add-test2
Already up to date.
```

これでリモートリポジトリの状態を取得することができました。

では、ブランチの確認をしてみます。
`-a`をつけることにより、ローカルリポジトリだけでなくリモートリポジトリも含んだブランチ情報を取得できます。

remote/origin/~のブランチはリモートリポジトリのブランチになります。

```
$ git branch -a
* master
  remotes/origin/feature-add-test2
  remotes/origin/master
```

リモートリポジトリの`feature-add-test2`をローカルリポジトリに持ってきたいのでcheckoutします。

コマンドは次のようになります。
`git checkout -b <ローカルに作成するブランチ名> <checkout元のブランチ名>`

```
$ git checkout -b feature-add-test2 origin/feature-add-test2
Branch 'feature-add-test2' set up to track remote branch 'feature-add-test2' from 'origin'.
Switched to a new branch 'feature-add-test2'
```

再度ブランチ情報を確認するとリモートリポジトリの内容をローカルに持ってきつつ、
作業ブランチも移動していることが確認できます。

```
$ git branch -a
* feature-add-test2
  master
  remotes/origin/feature-add-test2
  remotes/origin/master
```

###修正作業の実施

`4. 作業中のブランチは定期的にプッシュする`に関しては定期的にpushを行うことようにしてください。
test2という文字を追加するだけでは一度のpushで済んでしまいますので、
「test2」と「テスト２」を2回に分けて追加してみます。

では、最初にsampleFileにtest1という文字を記述した流れと同じ感じでtest2も追記してみます。
※現在のブランチがfeature-add-test2であることを確認してから行ってください。

ちなみに追加後は下記のような状態になりました。

```
$ cat sampleFile 
test1
test2
```

では、修正が行えたので**push**したいと思います。

```
$ git add sampleFile    // addしてます

$ git commit -m "add test2"    // commitしてます
[feature-add-test2 9c7a38c] add test2
 1 file changed, 1 insertion(+)

$ git push    // pushしてます
Enter passphrase for key '/Users/ryosuke/.ssh/id_rsa': 
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 263 bytes | 263.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:onishi-app/github-flow.git
   f4e4a23..9c7a38c  feature-add-test2 -> feature-add-test2
```

ここまでの状態を確認してみます。

###ターミナルの場合

masterブランチに移動します。

```
$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
```

sampleFileの内容を確認します。
先ほど記載したtest2がmasterブランチには反映していないことが確認できます。

```
$ cat sampleFile 
test1
```

feature-add-test2ブランチに移動します。

```
$ git checkout feature-add-test2
Switched to branch 'feature-add-test2'
Your branch is up to date with 'origin/feature-add-test2'.
```

feature-add-test2ブランチのsampleFileは修正されていることが確認できます。

```
$ cat sampleFile 
test1
test2
```

###ブラウザの場合
masterブランチには1回目の状態が記載されています。
（1回目のコミットですと表示されています。）
![スクリーンショット 2021-02-20 14.12.11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/a63f6a92-4acd-9463-e9f3-384b0c7a916c.jpeg)

次に、feature-add-test2ブランチを確認したいので、
masterをクリックし、feature-add-test2を選択してください。
![スクリーンショット 2021-02-20 14.13.15.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/05376ff0-31df-f5f8-e375-428341edb1ae.jpeg)

するとこちらは先ほどpushした内容が反映されていることがわかります。
![スクリーンショット 2021-02-20 14.14.35.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/7d7bfcc4-2ddb-adf0-7492-6de7d7abdfea.jpeg)

確認後、テスト２という文字を追記して同じことをおこないます。
追加や確認などの手順は省略しますが、確認したい方は先ほどの手順で確認してみてください。


##Pull Requestとマージ

次に`5. Githubのプルリクエストを利用してレビューを行なってから、masterブランチにマージする`を行います。

先ほどブランチを分けて修正を行いました。
全ての実装が完了しデプロイできる状態だ！となりましたら次はmasterブランチにマージすることになります。

ですが、ただマージするだけでは安全性が低いので、
上司などの上の立場の方に修正点をチェックしてもらう必要があります。

そこで使える便利な機能が`Pull Request`です。
Pull Requestを行うことにより、リポジトリの管理者（上司の方々）が修正内容を確認し
問題がなければマージを行ってもらうことができます。

Pull Requestのやり方は、下記のような流れになります。
① リモートリポジトリのクローンをローカルに作成 -> 実施済み
② ローカルリポジトリで作業用のブランチを作成 -> 実施済み
③ 作業用ブランチの内容をリモートリポジトリにpushする -> 実施済み
④ ブラウザからPull Requestの作成 -> これから実施

作業用ブランチを作らないでmasterで修正を行ってpushをしても
Pull Requestを行うことができませんので注意してください。

では、ブラウザからPull Requestを作成します。

今までの作業を実施すると、ブラウザには赤枠の内容が表示されているはずです。
`Compare & Pull Request`をクリックします。
![スクリーンショット 2021-02-20 14.22.28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/0ba09842-9717-ecdf-cf09-ead99291c6da.jpeg)

コメント欄には適当にそれっぽいことを記入しておきます。
本来でしたら作業内容などを記入するのかと思います。

記入後に`Create pull request`をクリックします。
![スクリーンショット 2021-02-20 14.34.59.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/f715b446-c2fc-edfd-88f5-7cef259fb5e1.jpeg)

masterブランチを表示し`Pull request`をクリックすると、
先ほど作成した作業用ブランチの名前でリクエストされています。
![スクリーンショット 2021-02-20 14.37.29.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/7e26ef17-9980-88c8-2635-d0b82798af31.jpeg)

このリクエストをクリックすると次の画面に移動します。

管理者はこのPull Requestの内容を確認してマージするかどうか判断します。

赤枠の部分が各コミットの内容になります。
「テスト２を追加しました」をクリックしてみると次の画面に移動します。
![スクリーンショット 2021-02-20 15.00.11.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/08d08ad2-cd49-fb63-df15-891eea143174.jpeg)



この画面ではこのコミット時の変更内容が分かりやすく表示されております。
![スクリーンショット 2021-02-20 15.01.34.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/20c5ab89-0d2f-0437-7029-e6573ae71df4.jpeg)


先頭に`＋`と記載されている箇所が追加した箇所です。
ここの修正に指摘したい場合は修正箇所にカーソルを合わせると青色の＋ボタンが表示されますでのクリックします。
![スクリーンショット 2021-02-20 15.03.53.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/6c357307-f046-8ecf-a574-19863cf7d9eb.jpeg)

すると下にテキストフィールドが表示されるので指摘内容を記載します。
その後右上の`Finish your Review`をクリックするとレビュー完了です。
![スクリーンショット 2021-02-20 15.04.23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/4b2e4af3-2a85-039e-d518-495669ce14a6.jpeg)

開発者は管理者からのレビューを修正し再度Pull Requestを送信します。
最終的に指摘がなくなってマージしてもいい状態まで仕上げます。

マージする場合は`Merge pull request`をクリックします。
![スクリーンショット 2021-02-20 15.07.42.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/3f001db5-ce0d-0e3b-ab82-042953fd124d.jpeg)

次に`Confirm merge`をクリックします。
![スクリーンショット 2021-02-20 15.08.05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/5ad12331-dacc-f9a4-2366-1ec330e85914.jpeg)

masterブランチの内容を確認するとfeature-add-test2の修正内容が反映されていることがわかります。
![スクリーンショット 2021-02-20 15.08.27.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/3f955640-0656-8883-4cfe-df173d626b5c.jpeg)


##ブランチの削除する

最後に`7. デプロイ後は速やかに作業していたブランチを削除する`を実施します。
作業が終了し必要なくなったブランチをいつまでもとっとく理由はないので削除の一択ですね。

branchesをクリックします。
![スクリーンショット 2021-02-20 15.13.09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/11670cf6-7611-9e72-5ee1-0762769df04e.jpeg)

いらないブランチのゴミ箱ボタンをクリックします。
![スクリーンショット 2021-02-20 15.13.28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/22a519b1-2ad0-a62b-42cb-20e8b5742bb3.jpeg)

branchesの数がmasterのみとなっていることが確認できればブランチの削除は完了です。
![スクリーンショット 2021-02-20 15.13.48.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/797483/58384ca1-8447-c769-a9e3-13219b3d35f7.jpeg)

ここまでで一連の流れは終了です。

#さいごに

どうでしょうか。私の説明で理解できた方がいらっしゃったら嬉しいですが・・・。
このような運用をすることにより、安全かつ迅速にサービスのアップデートを行うことができます。

GitHub Flowだけでなく他にもさまざまな運用方法があるので
ぜひ自分に合うものを見つけてみてください！

かなり長くなってしまいましたが最後まで読んで下さってありがとうございました。