研究室用に作成したGitHubマニュアルを共有する③~ブランチとマージについて~

# 初めに
今回は今までの記事の続きになります。お付き合い頂ければ幸いです。
[研究室用に作成したGitHubマニュアルを共有する① ～Gitの歴史と環境構築について～](https://qiita.com/renesisu727/items/cf86b1d2df7f871f383f)
[研究室用に作成したGitHubマニュアルを共有する②~GitHubにpushするまでのコマンドまとめ~](https://qiita.com/renesisu727/items/737faf0829003dce431b)


##GitHubとのやりとりについて
次のコマンドで、設定しているリモートリポジトリの情報を表示することができます。

```
git remote # リモートのショートカット名を表示
git remote -v # リモートのURLを表示 
```
>origin
>origin  https://github.com/hangi4343/qiita_practice.git (fetch)
>origin  https://github.com/hangi4343/qiita_practice.git (push)

次のコマンドで、GitにGitHubのリポジトリを登録することができます。

```
git remote add <リモート名> <リモートのURL>
```

前回の記事では、originというショートカットにGitHubのリポジトリを登録しました。

## ブランチについて
GitHubではブランチという概念があります。ブランチとは、開発を枝分かれさせた際の一つ一つの枝のことです。

実際に以下のコマンドで現在のブランチを確認してみましょう。

```
git branch
```

>\* master

ブランチを増やしていないため、今はmasterブランチというブランチしかありません。ブランチを増やすことを「ブランチを切る」と言ったりします。次のコマンドでブランチを切ってみましょう。

```
git branch branch_test
```

このコマンドを打つと、新しくbranch_testブランチを切ることができます。もう一度git branchコマンドで確認してみましょう。

```
git branch
```

>  branch_test
>\* master

branch_testという新しいブランチができていることが確認できます。*がついているのが今現在作業しているブランチになっています。

ここまでで実際にブランチを作成してみました。では、ブランチという概念についてもう少し細かく見ていきましょう。

以下の図を見てください
![17.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/68d5eb17-ecad-22a6-2ce2-0d9187c8bf7c.png)

Gitはコミットによってファイルの状態が変化します。

つまり、どのコミットの状態を保持しているかで、ファイルの状態が決まるのです。

ブランチとは、どの部分のコミットの状態を保持しているかのポインタであるということができます。今、branch_testブランチを切っただけではmasterブランチとbranch_testブランチは同じコミットを指しているため、ファイルの状態は全く同じになります。

また、HEADというものも存在し、このHEADはいずれかのブランチを指し示すことで現在のブランチを決定しています。今はmasterブランチにいるので、HEADはmasterを指しています。

HEADが指すブランチを変更するには、git checkoutコマンドを使います。

```
git checkout branch_test
```

これで現在のブランチを変更することができました。確認してみましょう。

```
git branch
```

>\* branch_test
>  master

図で見ると以下のように変化したことになります。
![18.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/7cc81a76-31e3-b1d7-8f4f-cf0440a3f11a.png)

この状態で変更を加えてcommitしてみましょう。lesson.pyを次のように変化させます。

```lesson.py
print('Hello GitHub')
print('create new branch')
```

この変更をcommitしましょう。

```
git add lesson.py
git commit -m "add create new branch"
```

git commit の-mオプションで、vimエディタを開かずにコメントを追記することができます。このcommitにより、次のように変化します。

![20.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/7c0913d5-25be-e1e6-ba7b-95853584ae1f.png)

この状態で、git checkoutコマンドによりmasterブランチに移動しましょう。どのようになるか分かりますか？

```
git checkout master
```

lesson.pyを確認してみましょう。以下のようになっていると思います。

```lesson.py
print('Hello GitHub')
```

print('create new branch')というコードが存在しないことが分かります。図解すると以下のようになります。
![21.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/aa5b3d32-45b2-9a1b-9c67-f3a838e0c235.png)

先ほどのコミットはbranch_testブランチにおいて行ったコミットであるため、masterブランチはコミット前の状態になっています。このようにしてブランチを切って開発を進めることで、複数人で開発をすすめることができます。

では、最後にmasterブランチにbranch_testブランチを統合して、コミット④をmasterブランチに反映させましょう。

このようにブランチを統合させることをマージといいます。以下のコマンドを打ちましょう。

```
git merge branch_test
```

このコマンドにより、masterブランチとbranch_testブランチがマージされました。図にすると次のようになります。
![22.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/b057f331-fae3-1cf8-efc8-4b090aa016be.png)

Gitにおいては、このようにブランチを切ってマージすることが開発の基本になります。また、このようなマージの仕方をとくにFast Forwardといいます。

最後に、必要なくなったbranch_testブランチを削除しましょう。

```
git branch -d branch_test
```

## GitHubから情報を取得する
リモートリポジトリが他の人からのプルリクエストにより変更した場合を考えてみましょう。自分は以下のようにgit_fetch.pyファイルを作成しました。
![15.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/9e5ad700-5bb7-c952-dad0-beb6cc8d57d2.png)

このようにリモートとローカルのリポジトリの状況に差異があるときには、ローカルのリポジトリを更新する必要があります。

リモートから情報を取得するときに用いるgit fetch コマンドとgit pullコマンドをみていきましょう。

### git fetchコマンドについて
今回はリモートのURLにoriginというショートカットを作成しているので、以下のコマンドでローカルに情報を保存することができます。

```
git fetch origin
```

git fetchコマンドを打つと、remotes/origin/masterというブランチにリモートの情報が保存されます。次のコマンドでブランチを確認してみてください。

```
git branch -a
```

>\* master
>remotes/origin/master

git branchコマンドを打つと、ローカルのgitのブランチが表示され、-aコマンドを打つと、remotesも含めた全てのブランチが表示されます。
*がついているのが今いるブランチです。

git fetchコマンドによりリモートのリポジトリをローカルのリポジトリに取り込むことができましたが、その情報はremotes/origin/masterというブランチに取り込まれており、現在のブランチであるmasterブランチには取り込まれていません。

mergeする前に、remotes/origin/masterにブランチを切り替えてみましょう。

```
git checkout remotes/origin/master
```

ファイルを確認すると、git_fetch.pyファイルがあるのが分かると思います。
確認が終わったら、元のmasterブランチに切り替えましょう。

```
git checkout master
```

それでは、remotes/origin/masterのブランチを現在のmasterブランチにマージしましょう。
コマンドは　git merge <ブランチ名>　でしたね。

```
git merge remotes/origin/master
```
これで現在のブランチを確認してみると、git_fetch.pyファイルが存在するのが分かります。

### git pullコマンドについて
git pullコマンドは、git fetchとgit mergeを合体させたようなコマンドです。
以下のような書式で用います。

> git pull ＜リモート名＞　＜ブランチ名＞


再びリモートリポジトリが他の人によって更新された場合を考えます。今回はgit_pull.pyファイルを追加します。
![24.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/2066a1b7-6682-67b0-e028-e313caed4255.png)

このリモートリポジトリの変更をローカルリポジトリで取得しましょう。以下のコマンドで取得できます。

```
git pull origin master
```

以上のコマンドで、masterブランチにgit_pull.pyファイルが追加されているのが確認できると思います。

## プルリクエストについて
それではプルリクエストについて解説します。

プルリクエストとは、自分の変更したコードをリポジトリに取り込んでもらうように依頼する機能になっています。

複数人で開発を行う際に、全員が好きなようにコードの変更をしてしまえば、今まで動いていたコードが動かなくなったり、質の悪い変更をしてしまうことがありますよね。

それを防ぐためにあるのがプルリクエストです。

自分の変更をリモートのリポジトリにマージする際に、他の人にレビューを依頼するようにお願いします。これがプルリクエストです。

それではプルリクエストまでの流れを以下に図解しました。
![25.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/fade12eb-aadd-4b79-bdba-98c1fdf7327e.png)

実際にプルリクエストの行ってみましょう。

以下のコマンドでブランチを最新の状態にしましょう。

```
git pull origin master
```

ブランチを最新の状態にした後は、ブランチを切っていきます。lesson_pull_requestブランチを作成しましょう。

```
git checkout -b lesson_pull_request
```

git checkoutに-bオプションをつけると、新しいブランチを作成しながらHEADを変更することができます。

次のようにlesson.pyファイルを変更しましょう。

```lesson.py
print('Hello GitHub')
print('create new branch')
print('lesson pull request')
```

lesson.pyをステージングエリアに追加します。

```
git add lesson.py
```

lesson.pyをローカルリポジトリにコミットしましょう。

```
git commit -m "add lesson pull request"
```

それではリモートリポジトリにlesson_pull_requestブランチをプッシュします。

```
git push origin lesson_pull_request
```

それでは[こちら](https://github.com/)からGitHubを開きます。

先ほどプッシュしたリモートリポジトリから、Pull requestのタブを開きましょう。

![27.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/93d3572d-5c59-01f5-4083-96881921490e.png)

Compare & pull requestを押した後、プルリクエストの題名と本文を入力し、Create pull requestボタンを押せばプルリクエストの完了です。

プルリクエストが完了したあとは、右側のReviewersからレビュアーを選択し、プルリクエストをレビューしてもらう人を選択しましょう。

以上でプルリクエストは終了です。

#終わりに

ここまででGitHubマニュアルは終了です。お付き合い頂きありがとうございました。

[研究室用に作成したGitHubマニュアルを共有する① ～Gitの歴史と環境構築について～](https://qiita.com/renesisu727/items/cf86b1d2df7f871f383f)
[研究室用に作成したGitHubマニュアルを共有する②~GitHubにpushするまでのコマンドまとめ~](https://qiita.com/renesisu727/items/737faf0829003dce431b)