gitロググラフを綺麗にするちょっとした技【基本編】

# gitログは綺麗に

ロググラフがごちゃごちゃしていると、履歴を追う時に心が折れます :sob: 
<img width="174" alt="ごちゃごちゃしたロググラフ例" src="https://qiita-image-store.s3.amazonaws.com/0/109136/fb7ddefe-9001-1b27-4f79-5c0900d48fba.png">
git flowで開発をしていると、分岐するのは仕方が無い時もあるのですが、明らかに必要ないのに分岐させている人をよく見ます。
チリも積もると全く読めない（読みたくない）グラフになってしまうので、必要ない分岐はさせないに越したことはありません。

# 頻繁に分岐が発生するパターン
チームで開発をしていると、**「pushしようとしたら他の人が先にpushしていた」**ということが頻繁に発生します。
まだgit経験が浅い人は、ここで分岐させてしまいます。

## 発生例
例えば、グラフがこの状態にあるとします。
<img width="464" alt="git-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/109136/6f73af06-c6bb-5ed6-c03f-64bfffffdceb.png">
commit2（f9b26f3）に対して、修正点をcommitして、pushしようとします。

```bash
(master)$ git add .
(master)$ git commit -m 'commit 4'
(master)$ git push origin master
```

しかし、他の人が先にpushしていたので、non-fast-forwardが発生してpushできませんでした。

```bash:pushしようとしてエラー
(master)$ git push origin master
To https://github.com/west-hiroaki/git-test.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/west-hiroaki/git-test.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

リモートを含めたヒストリはこうなっています。
commit3（d3dcdd3）が、他の人が先にpushした修正です。
<img width="460" alt="git-3.png" src="https://qiita-image-store.s3.amazonaws.com/0/109136/df66bb42-e22d-5256-e417-3071ee1ecbab.png">

この場合、pushするためにどういうアクションをとるべきでしょうか？

## 分岐させちゃうパターン :scream: 
ここでpullすると、分岐してしまいます。

```bash:pullコマンド実行（コメント入力は省略）
(master)$ git pull origin master
```
pullするとマージされるので、当然ながらこうなります。
<img width="698" alt="git-4.png" src="https://qiita-image-store.s3.amazonaws.com/0/109136/685fe439-e6d6-ae54-dd31-03978b5691e8.png">

## 分岐させないパターン :kissing_heart: :two_hearts: 
rebaseすると、分岐が発生しません。

```bash:rebaseコマンド実行
(master)$ git fetch -p
(master)$ git rebase remotes/origin/master
First, rewinding head to replay your work on top of it...
Applying: commit 4
```
<img width="420" alt="git-5.png" src="https://qiita-image-store.s3.amazonaws.com/0/109136/7bad9db1-38e0-11a0-61ee-6b2334abebef.png">

rebaseコマンドによって、指定されている```remotes/origin/master``` のコミット（commit3：d3dcdd3）に対して、ローカルのコミット（commit4）を付け直すからです。
（コミットIDが、```90129be``` から```0c4c338``` に変わっているところからも付け直していることが分かります）

画像を見て分かる通り、ロググラフが一直線になり、時系列もすっきりします。

:bangbang: ちなみに、rebaseする前に```fetch``` をしないと、ローカルのremote情報が古いままの可能性があります。その場合、rebaseされませんので行っておいた方が無難です。

# おまけ：pullしちゃった時の回避方法Tips
ここからはおまけです。

pushしてnon-fast-forward状態であることに気がつく前に、pullしてしまって、コメント入力画面になってしまったらどうすればいいでしょうか？

```bash
(master)$ git pull origin master
```
↓

```bash:コメント入力画面
Merge branch 'master' of https://github.com/west-hiroaki/git-test

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
```
このまま```:wq``` するとマージが完了するので、グラフが分岐してしまいます。

## 回避方法
結構最近まで読んでませんでしたが、ちゃんと下にコメントで方法が書いてありました。

> Lines starting with '#' will be ignored, and an empty message aborts the commit.

全てをコメント状態にすればabort状態に出来るとのことなので、1行目をコメントにします。（自分は面倒くさいので1行目を消しちゃってますが）

```bash:コメント入力画面：1行目をコメントアウト
# Merge branch 'master' of https://github.com/west-hiroaki/git-test

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
```

そして```:wq``` でエディタを抜けると、マージが中断された状態になっています。

```bash
(master|MERGING)$
```

後は、abortさせればOKです。

```bash
(master|MERGING)$ git merge --abort
```

そうするとpullする前の状態に戻りますので、rebaseすることが可能になります。

```bash
(master)$
```