分かったつもりで分かっていなかったGit、GitHub②

第一弾はこちらです。
[分かったつもりで分かっていなかったGit、GitHub①](https://qiita.com/mumucochimu/items/7e7d7875f0e9adee041d)

前回に引き続き、分かったつもりで分かっていなかった内容をまとめます！
間違い等あればご指摘お願い致します！

# conflicts(コンフリクト)

コンフリクトは衝突という意味で、別々のブランチで`同じファイル`の`同じ行`をそれぞれ変更され差異が発生した状態でマージしようとすると起こります。
違うファイルの変更なら起こらないし、同じファイルでも行が違えば起こらないです。

![自由 - Frame 1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051152/4ae0d2b4-5052-4163-2ef3-86fdf8d3e83b.jpeg)

コンフリクトって怖いイメージありますけど、実はそんなに難しくなく修正できるのです。

もしコンフリクトが起きるとGitHub上でエラーが出ます。
で、コードを見てみるとコンフリクトしている部分を以下のように`<<<`や`>>>`で教えてくれます。

```html

<div class="playlist">
  <ul>
    <li>ナノセカンド</li>
    <li>ハルジオン</li>
<<<<<<<<<<
    <li>KINJITO</li>
    <li>MONDO PIECE</li>
==========
    <li>在るべき形</li>
    <li>THE OVER</li>
>>>>>>>>>>
  </ul>
</div>
```

<<<<<から>>>>>までがコンフリクトしている箇所です。
GitHub上のエディタでそのまま直せます。
正しい状態に直してマージすればOKです。
その際、<<<<<や>>>>>は不要なので消すことを忘れずに。


# ブランチの作成や移動

いろいろなコマンドがありますよね。

#### ブランチの一覧表示
私は心配性なので今いるブランチを頻繁に確認してしまう...。

```
// *が今いるブランチ
$ git branch
* develop
  sample1
  sample2

// -aをつけるとリモート追跡ブランチも見れる
$ git branch -a
* develop
  sample1
  sample2
  remotes/origin/HEAD -> origin/main
  remotes/origin/main
```

#### ブランチの作成
今いるブランチから派生して作成されます。
例えば今いるブランチがdevelopで以下のコマンドを実行したらdevelopから派生したsample1ブランチができるということです。

```
$ git branch sample1
```

#### ブランチの移動

```
$ git checkout sample1
```

#### ブランチの作成と移動を一緒に行う

```
$ git checkout -b sample1
```

#### ブランチの削除
マージ済みなら以下のコマンドです。

```
$ git branch -d sample1
```

マージされる前のブランチを削除したい場合は以下のコマンドです。

```
$ git branch -D sample1
```

# revert(リバート)

過去のコミットを取り消したい時に使うものなのですが`消す`のではなく`打ち消す内容をコミットする`のが特徴です。
分かりづらいですよね。
例えば以下のような追加をしたコミットがあるとします。

```html
<div class="title">
  <h2>ハンバーグ</h2>

  //以下を追加
  <p>ひき肉</p>

</div>
```

で、これを取り消す。
コマンドは以下です。

```
//消したいコミットを確認。確認したらqを押して抜ける。
$ git log

//該当のIDをコピーし以下のコマンド
$ git revert <打ち消したいコミットID>
```

そうすると以下のように追加する前に戻ります。

```html
<div class="title">
  <h2>ハンバーグ</h2>
</div>
```

revertは追加したコミットと反対の内容でコミットをしているだけなので、打ち消しても以前の追加したコミット履歴は消えません。
完全に消すのは`reset`というものがありますが履歴も残らないのであまり使わない方がいいようです。
revertはそのrevertをさらにrevertできるので打ち消しても元に戻せます。
便利ですねー。


# rebase(リベース)

先輩が言ってました。
「rebaseは歴史の元を改変することだよ」と。
名前の通り、根本を植え替えるということでしょう。

以下は先輩が分かりやすく説明してくれた例です。

![自由 - Frame 2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051152/206a1cac-4544-071c-21fb-fc4a0e7d383a.jpeg)

上記のように日本史ブランチから日本史Aブランチ、日本史Bブランチが作成されています。
これはつまり、縄文時代から始まった日本史と奈良時代から始まった日本史があるということです。
大変ですね。

マージすると、その二つの世界線があった上で一つの世界に合体するという感じですが、
リベースはブランチの付け根を付け替えることができるので、元々一つの世界だったようにすることができます。

![自由 - Frame 2 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051152/a31acaa4-2422-8142-483e-aa5bea733a6f.jpeg)

こんな感じで日本史Bブランチの根本を付け替えることができます。

ログが見やすくなったりするのですが、リモートリポジトリでやってしまうと誰かのコミットに影響を与えてしまうので基本的にはローカルでやるのが正しいみたいですね。
(プロジェクトによってルールはあると思いますが)
私としては基本的にはマージで対応できればその方が安全だなと思ってます。

以下、リベースのコマンドです。

```
//先ほどの例のように日本史Aブランチに日本史Bブランチをつなげる場合
$ git rebase 日本史A
```

また、リベースはオプションをつけることでコミットを一つにまとめたりできるようです。

例えば以下の例えのように古墳時代と飛鳥時代を一つにまとめたいとします。
![自由 - Frame 2 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1051152/aac6fa48-ab3b-a084-ad5b-a583340f56c7.jpeg)

その場合のコマンドは以下です。

```
//以下のコマンドでまとめる一つ前である弥生時代のコミットIDを調べる
$ git log

//以下のコマンドでviが開く
$ git rebase -i <弥生時代のコミットID>

//開いたviは以下のイメージ
pick d9a1f0a 古墳時代
pick 400f34a 飛鳥時代

//pickをsquashに変更する
pick d9a1f0a 古墳時代
squash 400f34a 飛鳥時代
```

上記の流れで一つにまとめることができます。
コミットを細かく分けすぎて見にくい時とかに使うといいですね！

以上です。