Gitのコマンド一覧(3) -clone, fetch, merge, pull-

# 概要
[Gitのコマンド一覧(2)](https://qiita.com/sepakTama/items/e861f0e5cfd75fe10f82)では、ブランチの考え方とリモートとローカルの関係性について話した。本ページでは、多人数で開発をする際によく必要とされる、cloneやpullであったり、ブランチを整理する際に用いられるrebaseについて説明する。

前提条件として、ローカルPCにgitのアカウントを登録しておく必要がある。（ローカルPCでgitコマンドを使えたらOK）


# 主に使っているコマンド
- init
- add
- commit
- push
- **clone**
- status
- log
- reflog
- branch
- checkout
- remote
- **fetch**
- **merge**
- **pull**
- rebase
- cherry-pick
- reset
- rm

## clone

```Git
git clone [http]
```

リモートリポジトリをローカルPCに複製する時に用いるコマンドである。複製したいディレクトリで上記のコマンド（[http]の部分は、githubもしくはgitLabのリモートリポジトリのページからコピーする必要あり）を実行することによって、リモートリポジトリの情報（ブランチの情報などすべての情報）をローカルPCに複製し、ローカルPCでの開発が可能となる。実際に複製されたかを確認する方法として、ターミナル上で`ls -a`コマンドを入力し、.gitが存在するかを確認すれば良い。（.git内部にブランチやgitのログが入っている）

`git clone`を行った際はmasterブランチにいるため、ブランチを切ったり、別のブランチにチェックアウトすることを忘れずに行おう。

# origin/masterって何？
自身のブログの[Gitのコマンド一覧(2)](https://qiita.com/sepakTama/items/e861f0e5cfd75fe10f82)までではイメージしやすいように説明を省いていたが、`git fetch`を説明する場合、より深い部分まで説明をしなければならないため、その部分について説明する。

origin/masterとは簡単にいうと「リモートリポジトリ（originという名前）のmasterブランチと繋がっているローカルリポジトリ」である。何を言っているのかというと、ローカルで新規追加（更新）したファイルが直接リモートリポジトリに反映されるのであれば、`git add`や`git commit`はいらないとは思わないだろうか。すなわち、ローカルからリモートへ情報を渡す際の中間層みたいなものがoriginなのである。イメージすると以下のようになる。（私の解釈では`git remote add origin`を行なった際にリモートにoriginの情報が追記されている。）

![git_origin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2207583/9b94f375-07f1-3832-527b-f2ba586edf8e.png)

自身が作業しているのはローカルのmasterブランチであり、`git add`、`git commit`を行うことによってローカルのorigin/master -> リモートのmasterブランチに反映されるという流れである。

## fetch
`git fetch`とはリモートリポジトリの情報をローカルのorigin/master ([リモートリポジトリ名]/[ブランチ名])に反映させるコマンドである。ここで注意するべきことはローカルのorigin/masterは更新されるが、自身が作業をしているmasterブランチは反映が更新されないことである。

```Git
git fetch [リモートリポジトリ名] [ブランチ名]
```

でコマンドを実行する。[ブランチ名]は省略可能であり、省略した場合、指定したリモートリポジトリの情報をすべて取ってくる。自身がmaster ブランチで作業をしており、リモートリポジトリと違う編集を加えた際に`git remote origin master`を実行したら以下のような挙動を起こす。（[参考](https://backlog.com/ja/git-tutorial/stepup/15/)）

![git_fetch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2207583/3a3d5027-043a-374b-8241-9bd4a9f7d069.png)


## merge
`git merge`とはローカルにある**リモート追跡ブランチ（今回ではorigin/master）を作業しているローカルブランチに取り込む**ためのコマンドである。

```Git
git merge [リモート追跡ブランチ]
```
を実行することで、ローカルにあるリモート追跡ブランチ（origin/master）の情報を自身が作業しているmasterブランチに取り込むことができる。リモートリポジトリ名がoriginで作業ブランチがmasterの場合、`git merge origin/master`を実行すれば良い。
上図の状態で`git merge origin/master`を行うと以下のような挙動となる。

![git_merge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2207583/4bb03424-4496-5b35-7223-400689970359.png)

### コンフリクトとは
`git merge`の図を見て、「あれ？同じ場所を編集していた場合どうなるんだ？」と感づいた人がいるかもしれない。具体的にはログCとログXで仮に同じファイルの同じ行に対して別の編集を行なっていた場合はログDはどうなるのだろうか？
答えは**コンフリクト（conflict）**が発生する。コンフリクトとは衝突のことで、git側が同じ箇所を修正しているためどっちの情報を取り入れればいいのかわからない状態となっており、そのコンフリクトを解消するまで実際にはログDは生じない。コンフリクトの解消方法としては、

- Cの変更箇所をガン無視する方法**（お勧めしないので説明は省く）**
- どちらの変更点を採用するか（もしくは両方採用するか）を選択する

が挙げられる。（他にもある場合は追記していく）
最近の開発エディタではgitを拡張機能として入れることができるものもあり、筆者はVSCodeを用いている。VSCodeの拡張機能にgitがあり、コンフリクトがあった場合その差分を見て（差分を見るコマンドもあるが、筆者は使わないので説明は省く）どちらを採用するかクリックするだけでコンフリクトの発生部分を解消することができる。
また、コンフリクトが発生した際にコンフリクトが発生した前の状態に戻したい場合は以下のコマンドで元に戻すことができる。

```terminal
> git merge --abort # コンフリクトが起きた後、まだ何もしてない場合
> git reset --hard HEAD #コンフリクト解消のためファイル編集を行なっていた場合
```
多人数で開発をしている場合どうしてもコンフリクトは生じてしまうが、出来るだけコンフリクトが起こらないように管理・運用をするべきである。

## pull
`git pull`は上記で説明した`git fetch`+ `git merge`を一連に実行してくれるコマンドである。以下のように実行することができる。

```Git
git pull [リモートリポジトリ名] [ブランチ名]
```

# 次のブログでは
[次のブログ](https://qiita.com/sepakTama/items/a568c0998a0864bfa8be)では`git rebase`や`git cherry-pick`など、ブランチやログの状態を改編（実際にはそのログも残る）するコマンドについて見ていく。

https://qiita.com/sepakTama/items/a568c0998a0864bfa8be