マージコミットとFast-forwardマージ

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

分岐元(ブランチ名: master)から新しいブランチ(ブランチ名: topic)を作成して、topicブランチで
いくつかcommitしたとします。

topicブランチでの作業が完了したので、masterブランチにcheckoutして、topicブランチをマージしました。

この際、topicブランチをマージするまでの間に、分岐元であるmasterブランチでcommitが実施されていたか、
いなかったかで、マージの挙動が変わります。

ここではその様子を掲載しています。


topicブランチのマージまでの間にmasterブランチでcommitがあった場合(マージコミットをつくる)
-------------------------------------------------------------------------------------------

masterブランチでfile1をcommit:

``` bash
$ git branch -l
* master
$ touch file1
$ git add file1
$ git commit -m "add file1"
```

topicブランチを作成して、checkoutする:

```
$ git checkout -b topic
$ git branch -l
  master
* topic
```

topicブランチでいくつかcommitする:

```
$ touch bar.txt
$ git add bar.txt
$ git commit -m "add bar.txt"

$ touch hoge.txt
$ git add hoge.txt
$ git commit -m "add hoge.txt"

$ touch foo.txt
$ git add foo.txt
$ git commit -m "add foo.txt"
```

masterブランチをcheckoutして、1回commitする:

```
$ git checkout master
$ git branch -l
* master
  topic

$ touch baz.txt
$ git add baz.txt
$ git commit -m "add baz.txt"
```

masterブランチをcheckoutしている状態で、topicブランチをマージする:

```
$ git branch -l
* master
  topic

$ git merge topic
Merge made by recursive.
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 bar.txt
 create mode 100644 foo.txt
 create mode 100644 hoge.txt
```

logを確認するとマージコミットがあることがわかる:

```

$ git log --graph
*   commit 508ae60c053e875ffa3620e713ffc2e66522a1d0
|＼  Merge: 70cac92 5a18a07
| | Author: 
| | Date:   Mon Apr 7 16:25:31 2014 +0900
| | 
| |     Merge branch 'topic'
| |   
| * commit 5a18a0775d1753ce745d94210ebeb94dd65e0c8b
| | Author: 
| | Date:   Mon Apr 7 16:24:16 2014 +0900
| | 
| |     add foo.txt
| |   
| * commit 05701c7baeb7f83c737bea748adc8e2fd1d0b84a
| | Author: 
| | Date:   Mon Apr 7 16:23:59 2014 +0900
| | 
| |     add hoge.txt
| |   
| * commit 55e5ea752d0210d6aff77ee767befd100531fa4b
| | Author: 
| | Date:   Mon Apr 7 16:23:36 2014 +0900
| | 
| |     add bar.txt
| |   
* | commit 70cac92b10f45c18c9e773d5df02118ce3f9ec3f
|/  Author: 
|   Date:   Mon Apr 7 16:25:20 2014 +0900
|   
|       add baz.txt
|  
* commit 3f177e59e46241ff907e50705fe1b218cce2f812
  Author: 
  Date:   Mon Apr 7 16:23:08 2014 +0900
  
      add file1
```


topicブランチのマージまでの間にmasterブランチでcommitがなかった場合(Fast-forwardマージ)
--------------------------------------------------------------------------------------------

masterブランチでfile1をcommit:

```
$ git branch -l
* master
$ touch file1
$ git add file1
$ git commit -m "add file1"
```

topicブランチを作成して、checkoutする:

```
$ git checkout -b topic
$ git branch -l
  master
* topic
```

topicブランチでいくつかcommitする:

```
$ touch bar.txt
$ git add bar.txt
$ git commit -m "add bar.txt"

$ touch hoge.txt
$ git add hoge.txt
$ git commit -m "add hoge.txt"

$ touch foo.txt
$ git add foo.txt
$ git commit -m "add foo.txt"
```

masterブランチをcheckoutしている状態で、topicブランチをマージする:

```
$ git checkout master
$ git branch -l
* master
  topic

$ git merge topic
Updating 800455e..afd5520
Fast-forward
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 bar.txt
 create mode 100644 foo.txt
 create mode 100644 hoge.txt
```

ログを確認すると、マージコミットがないことがわかる:

topicブランチでcommitした`afd5520d71edc63591e144041906c43a1170e2bb`にHEADが向けられていることがわかる。

```
$ git log --graph
* commit afd5520d71edc63591e144041906c43a1170e2bb
| Author: 
| Date:   Mon Apr 7 15:55:01 2014 +0900
| 
|     add foo.txt
|  
* commit b4ac2876784a2b1b3fe351c0ae30508aef5aaa94
| Author: 
| Date:   Mon Apr 7 15:54:43 2014 +0900
| 
|     add hoge.txt
|  
* commit 90248370cc9fa042d3dc547f1faa0739a3ed9174
| Author: 
| Date:   Mon Apr 7 15:54:14 2014 +0900
| 
|     add bar.txt
|  
* commit 800455eca7109d492897831aea0eb101ac73b56d
  Author: 
  Date:   Mon Apr 7 15:53:21 2014 +0900
  
      add file1
```


強制的にマージコミットを作成
-------------------------------

上記のようにtopicブランチをmasterブランチにマージした情報を消さないために
強制的にマージコミットを作成する方法がある。

masterブランチでfile1をcommit:

```
$ git branch -l
* master
$ touch file1
$ git add file1
$ git commit -m "add file1"
```

topicブランチを作成して、checkoutする:

```
$ git checkout -b topic
$ git branch -l
  master
* topic
```

topicブランチでいくつかcommitする:

```
$ touch bar.txt
$ git add bar.txt
$ git commit -m "add bar.txt"

$ touch hoge.txt
$ git add hoge.txt
$ git commit -m "add hoge.txt"

$ touch foo.txt
$ git add foo.txt
$ git commit -m "add foo.txt"
```

masterブランチをcheckoutしている状態で、topicブランチをマージする:

この時、masterブランチにはコミットが一度もなかったので、defaultではFast-forwardマージがされてしまう。
そのため、--no--ffオプションで強制的にマージコミットを作り、Fast-forwardマージを抑止する。

```
$ git checkout master
$ git branch -l
* master
  topic

$ git merge --no-ff topic                                  
Merge made by recursive.
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 bar.txt
 create mode 100644 foo.txt
 create mode 100644 hoge.txt
```

ログを確認すると、マージコミットが作成されていることがわかる:

```
$ git log --graph
*   commit d217d8841f4ac81b531db8221b31acdba0603970
|＼  Merge: 09deb12 f7907f7
| | Author: 
| | Date:   Mon Apr 7 16:01:38 2014 +0900
| | 
| |     Merge branch 'topic'
| |   
| * commit f7907f7e2691ab5eaf883040157b64987d250dd8
| | Author: 
| | Date:   Mon Apr 7 15:59:55 2014 +0900
| | 
| |     add foo.txt
| |   
| * commit 1fadfbd8295924a1ed731a13e503476cce9996de
| | Author: 
| | Date:   Mon Apr 7 15:59:35 2014 +0900
| | 
| |     add hoge.txt
| |   
| * commit 80729ac76f336def90e049876c6fe7367b88fa3d
|/  Author: 
|   Date:   Mon Apr 7 15:59:17 2014 +0900
|   
|       add bar.txt
|  
* commit 09deb1297e3c5b3abfa6fb1bc1e5c06958e4d7dd
  Author: 
  Date:   Mon Apr 7 15:58:40 2014 +0900
  
      add file1
```