git rebaseでsquashした場合とfixupした場合の違い

はじめに
---------

ここでは`git rebase -i [commit]`コマンドでsquashした場合と
fixupした場合の違いについて実行例を説明します。


squashの場合
-------------

ファイルを作成

```bash
$ vi file1
add file
:wq

$ git add file1

$ git commit -m "add file1"
```

何度かファイルを更新する

```bash
$ vi file1
edit 1
:wq

$ git commit -am "edit 1"

$ vi file1
edit 2
:wq

$ git commit -am "edit 2"

$ vi file1
edit 3
:wq

$ git commit -am "edit 3"
```

ファイルを参照する

```bash
$ cat file1 
add file
edit 1
edit 2
edit 3
```

ログを確認する

```bash
$ git log                                                  
commit 7bce8c8e38c743073c2e889fd9cdd235274b99c2
Author: spam ham
Date:   Mon May 26 16:33:39 2014 +0900

    edit 3

commit 146a328333019dabf0c53747298c514cedf195e0
Author: spam ham
Date:   Mon May 26 16:33:26 2014 +0900

    edit 2

commit aa5b78285219c6dbc5b1c84a2820fef70cade33f
Author: spam ham
Date:   Mon May 26 16:33:11 2014 +0900

    edit 1

commit dce39a9bc0a05cc98d6f4c6028a584f9f64b0eb8
Author: spam ham
Date:   Mon May 26 16:31:50 2014 +0900

    add file1
```

squashする

```bash
$ git rebase -i HEAD~3
pick aa5b782 edit 1
pick 146a328 edit 2
squash 7bce8c8 edit 3 <- これをsquashする

# Rebase dce39a9..7bce8c8 onto dce39a9
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
```

squashを指定したあとに`:wq`でエディタを保存すると、コミットメッセージを
編集する画面に切り替わる

```bash
# This is a combination of 2 commits.
# The first commit's message is:

edit 2

# This is the 2nd commit message:

edit 3

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Not currently on any branch.
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   file1
#
```

下記のようにコミットメッセージを変更して保存します

```bash
# This is the 2nd commit message:

edit 2 & 3

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Not currently on any branch.
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   file1
#
```
	
ログを見てみると、コミットが一つにまとめられ、編集したとおりの
メッセージになっています

```bash
$ git log
commit 098d8e633eac2e4c6af0cbc84bb88aefe65c5e39
Author: spam ham
Date:   Mon May 26 16:33:26 2014 +0900

    edit 2 & 3

commit aa5b78285219c6dbc5b1c84a2820fef70cade33f
Author: spam ham
Date:   Mon May 26 16:33:11 2014 +0900

    edit 1

commit dce39a9bc0a05cc98d6f4c6028a584f9f64b0eb8
Author: spam ham
Date:   Mon May 26 16:31:50 2014 +0900

    add file1
```

ファイルを参照する

```bash
$ cat file1 
add file
edit 1
edit 2
edit 3
```

fixupの場合
-------------

ファイルを作成

```bash
$ vi file1
add file
:wq

$ git add file1

$ git commit -m "add file1"
```

何度かファイルを更新する

```bash
$ vi file1
edit 1
:wq

$ git commit -am "edit 1"

$ vi file1
edit 2
:wq

$ git commit -am "edit 2"

$ vi file1
edit 3
:wq

$ git commit -am "edit 3"
```

ファイルを参照する

```bash
$ cat file1 
add file
edit 1
edit 2
edit 3
```

ログを確認する

```bash
$ git log
commit c27b39074da477ba9aa5f1b435d35dd6cffbf2f6
Author: spam ham
Date:   Mon May 26 16:41:18 2014 +0900

    edit 3

commit da03e7917c373046f71cf9f14a56fadf8371dc5d
Author: spam ham
Date:   Mon May 26 16:41:04 2014 +0900

    edit 2

commit d0c4d4aa71e2eabc4a075a24d1bdd49c2a35d486
Author: spam ham
Date:   Mon May 26 16:40:52 2014 +0900

    edit 1

commit 74893929df6cd79a4679dc2c739ca197381fee95
Author: spam ham
Date:   Mon May 26 16:40:35 2014 +0900

    add file1
```

fixupする

```bash
$ git rebase -i HEAD~3
pick d0c4d4a edit 1
pick da03e79 edit 2
fixup c27b390 edit 3 <- これをfixupする

# Rebase 7489392..c27b390 onto 7489392
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
```

fixupの場合はsquashのようにメッセージの編集は開かれず
fixupしたメッセージはなくなります。

	
ログを見てみると、コミットが一つにまとめられ、fixupした
コミットのメッセージが消えています。

```bash
$ git log                                                  
commit c819c6cc2479daf0ce1a27216899db120d7c7800
Author: spam ham
Date:   Mon May 26 16:41:04 2014 +0900

    edit 2

commit d0c4d4aa71e2eabc4a075a24d1bdd49c2a35d486
Author: spam ham
Date:   Mon May 26 16:40:52 2014 +0900

    edit 1

commit 74893929df6cd79a4679dc2c739ca197381fee95
Author: spam ham
Date:   Mon May 26 16:40:35 2014 +0900

    add file1
```

ファイルを参照する

```bash
$ cat file1 
add file
edit 1
edit 2
edit 3
```