git rebaseの検証

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

git rebaseの挙動について数パターン検証を実施しました。

ここでは分岐元ブランチを**master**、分岐先ブランチを**topic**として
説明をしていきます。


topicブランチでrebase時に競合が発生しないケース1
--------------------------------------------------

> topicブランチの作業中にmasterブランチ側で新規のファイルが
> 追加され、その後topicブランチ側でrebaseする様子を説明します。
> 最終的にはmasterブランチ側からtopicブランチをマージします。


masterブランチでmaster_file1をcommit

```bash
$ touch master_file1
$ git add master_file1
$ git commit -m "add master_file1"
```

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

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

topicブランチでcommitする

```bash
$ touch topic_file1
$ git add topic_file1
$ git commit -m "add topic_file1"
```

topicブランチのログを見てみる

```bash
$ git log -l
commit 8f699a5f3a50ccb3c5b214656086a707fbbdfeec
Author: spam ham
Date:   Fri Apr 25 14:50:56 2014 +0900

    add topic_file1

commit 1d46277f8c83e3e9573c31c23d3c3386d1592774
Author: spam ham
Date:   Fri Apr 25 14:49:48 2014 +0900

    add master_file1
```

masterブランチをcheckoutして、fileを追加する

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

$ touch master_file2
$ git add master_file2
$ git commit -m "add master_file2"
```

再度topicブランチをcheckoutして、rebaseする

```bash
$ git checkout topic
Switched to branch 'topic'
$ git branch -l
  master
* topic

$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: add topic_file1
```

ログを確認してみる

> topicブランチがmasterブランチの最新のコミットに
> つなぎ替えられている。

```bash
$ git log -l                                              
commit 2fd51d15af10ceb9c2e665a08fac5bbdf14e433b
Author: spam ham
Date:   Fri Apr 25 14:50:56 2014 +0900

    add topic_file1

commit 97912a14f399cd509a5113d50a9cb0070a3dc1ed
Author: spam ham
Date:   Fri Apr 25 14:52:36 2014 +0900

    add master_file2

commit 1d46277f8c83e3e9573c31c23d3c3386d1592774
Author: spam ham
Date:   Fri Apr 25 14:49:48 2014 +0900

    add master_file1
```

masterブランチにcheckoutして、topicブランチをマージする

> ここではFast-forwardされないよう、オプションに--no-ffをつける

```bash
$ 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 topic_file1
```

masterブランチでログを確認してみる

```bash
$ git log --graph                                         
*   commit a5a3b795fd94b5f1da414c958e9ee8d8fdefcdd8
|\  Merge: 97912a1 2fd51d1
| | Author: spam ham
| | Date:   Fri Apr 25 15:12:23 2014 +0900
| | 
| |     Merge branch 'topic'
| |   
| * commit 2fd51d15af10ceb9c2e665a08fac5bbdf14e433b
|/  Author: spam ham
|   Date:   Fri Apr 25 14:50:56 2014 +0900
|   
|       add topic_file1
|  
* commit 97912a14f399cd509a5113d50a9cb0070a3dc1ed
| Author: spam ham
| Date:   Fri Apr 25 14:52:36 2014 +0900
| 
|     add master_file2
|  
* commit 1d46277f8c83e3e9573c31c23d3c3386d1592774
  Author: spam ham
  Date:   Fri Apr 25 14:49:48 2014 +0900
  
      add master_file1
```

masterブランチの作業ツリーにあるファイルを確認する

```bash
$ ls                                                      
master_file1  master_file2  topic_file1
```


topicブランチでrebase時に競合が発生しないケース2
--------------------------------------------------

> topicブランチの作業中にmasterブランチ側で既存ファイル**master_file1**が
> 編集され、その後topicブランチ側でrebaseする様子を説明します。
> 最終的にはmasterブランチ側からtopicブランチをマージします。


masterブランチでmaster_file1をcommit

```bash
$ touch master_file1
$ git add master_file1
$ git commit -m "add master_file1"
```

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

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

topicブランチでcommitする

```bash
$ touch topic_file1
$ git add topic_file1
$ git commit -m "add topic_file1"
```

topicブランチのログを見てみる

```bash
$ git log -l
commit 7b4204ff3eb14372283574cc51e0291d6b948e36
Author: spam ham
Date:   Fri Apr 25 15:03:29 2014 +0900

    add topic_file1

commit 5172e127b47cc58859e169bb23d299f849488cc8
Author: spam ham
Date:   Fri Apr 25 15:02:56 2014 +0900

    add master_file1
```

masterブランチをcheckoutして、master_file1を編集する

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

$ vi master_file1
1 * master branch <-1行目を書き換える
git commit -am "ecit master_file1"
```

再度topicブランチをcheckoutして、rebaseする

```bash
$ git checkout topic
Switched to branch 'topic'
$ git branch -l
  master
* topic

$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: add topic_file1
```

ログを確認してみる

> topicブランチがmasterブランチの最新のコミットに
> つなぎ替えられている。

```bash
$ git log -l                                              
commit 9982a206a6465b79035ad996bb6c5df99d888890
Author: spam ham
Date:   Fri Apr 25 15:03:29 2014 +0900

    add topic_file1

commit 46c64813617c21a0d0c80355d5ef9b1f42160f41
Author: spam ham
Date:   Fri Apr 25 15:08:16 2014 +0900

    ecit master_file1

commit 5172e127b47cc58859e169bb23d299f849488cc8
Author: spam ham
Date:   Fri Apr 25 15:02:56 2014 +0900

    add master_file1
```

masterブランチにcheckoutして、topicブランチをマージする

> ここではFast-forwardされないよう、オプションに--no-ffをつける

```bash
$ 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 topic_file1
```

masterブランチでログを確認してみる

```bash
$ git log --graph
*   commit a00615e2350db3046de20f87457624fe8632d3de
|\  Merge: 46c6481 9982a20
| | Author: spam ham
| | Date:   Fri Apr 25 15:17:38 2014 +0900
| | 
| |     Merge branch 'topic'
| |   
| * commit 9982a206a6465b79035ad996bb6c5df99d888890
|/  Author: spam ham
|   Date:   Fri Apr 25 15:03:29 2014 +0900
|   
|       add topic_file1
|  
* commit 46c64813617c21a0d0c80355d5ef9b1f42160f41
| Author: spam ham
| Date:   Fri Apr 25 15:08:16 2014 +0900
| 
|     ecit master_file1
|  
* commit 5172e127b47cc58859e169bb23d299f849488cc8
  Author: spam ham
  Date:   Fri Apr 25 15:02:56 2014 +0900
  
      add master_file1
```

masterブランチの作業ツリーにあるファイルを確認する

```bash
$ ls                                                      
master_file1  topic_file1

$ cat master_file1 
* master branch
```


topicブランチでrebase時に競合が発生するケース
-----------------------------------------------

> topicブランチの作業中にmasterブランチ側で既存ファイル**master_file1**が
> 編集されるが、topicブランチ側でも**master_file1**を更新してしまっていて
> rebaseした際に競合が発生してしまうケースです。

> topicブランチ側で競合を解決し、最終的にはmasterブランチ側からtopic
> ブランチをマージします。


masterブランチでmaster_file1をcommit

```bash
$ touch master_file1
$ git add master_file1
$ git commit -m "add master_file1"
```

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

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

topicブランチでcommitする

```bash
$ touch topic_file1
$ git add topic_file1
$ git commit -m "add topic_file1"
```

topicブランチのログを見てみる

```bash
$ git log -l                                              
commit 0c7eb5e105e38454df86d737c6ae52a9a4d04953
Author: spam ham
Date:   Fri Apr 25 15:52:42 2014 +0900

    add topic_file1

commit af5b2b29d575cb617cafa0408edf94fe26cd6997
Author: spam ham
Date:   Fri Apr 25 15:52:17 2014 +0900

    add master_file1
```

masterブランチをcheckoutして、master_file1を編集する

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

$ vi master_file1
1 * master branch <-1行目を書き換える

git commit -am "edit master_file1 by master branch"
```

再度topicブランチをcheckoutして、master_file1を編集する

```bash
$ git checkout topic
Switched to branch 'topic'
$ git branch -l
  master
* topic

$ vi master_file1
1 * topic branch <-1行目を書き換える

$ git commit -am "edit master_file1 by topci branch"
```

ログを確認してみる

```bash
$ git log -l
commit a919d02bf25a5f24db9d1df5c34ae2f32772d673
Author: spam ham
Date:   Fri Apr 25 15:55:48 2014 +0900

    edit master_file1 by topci branch

commit 0c7eb5e105e38454df86d737c6ae52a9a4d04953
Author: spam ham
Date:   Fri Apr 25 15:52:42 2014 +0900

    add topic_file1

commit af5b2b29d575cb617cafa0408edf94fe26cd6997
Author: spam ham
Date:   Fri Apr 25 15:52:17 2014 +0900

    add master_file1
```

topicブランチ側でrebaseする

> 競合が発生した

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

$ git rebase master                                       
First, rewinding head to replay your work on top of it...
Applying: add topic_file1
Applying: edit master_file1 by topci branch
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging master_file1
CONFLICT (content): Merge conflict in master_file1
Failed to merge in the changes.
Patch failed at 0002 edit master_file1 by topci branch

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".
```

競合を解決する

```bash
$ vi master_file1
<<<<<<< HEAD
* master branch
=======
* topic branch
>>>>>>> edit master_file1 by topci branch
↓

* master branch
* topic branch
```

リベースを続行する

```bash
$ git add master_file1
$ git rebase --continue
Applying: edit master_file1 by topci branch
```

ログを確認する

```bash
$ git log -l
commit 622730cac98bcbdfa65c6a8e3bf396c9d7411efb
Author: spam ham
Date:   Fri Apr 25 15:55:48 2014 +0900

    edit master_file1 by topci branch

commit cb6981979432a82be38161897527987ae285fdde
Author: spam ham
Date:   Fri Apr 25 15:52:42 2014 +0900

    add topic_file1

commit 48cfe32d78c91ee66e049d639e81f9de5589ffc5
Author: spam ham
Date:   Fri Apr 25 15:54:40 2014 +0900

    edit master_file1 by master branch

commit af5b2b29d575cb617cafa0408edf94fe26cd6997
Author: spam ham
Date:   Fri Apr 25 15:52:17 2014 +0900

    add master_file1
```

masterブランチにcheckoutして、topicブランチをマージする

> ここではFast-forwardされないよう、オプションに--no-ffをつける

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

$ git merge --no-ff topic
Merge made by recursive.
 master_file1 |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 topic_file1
```

masterブランチでログを確認してみる

```bash
$ git log --graph                                         
*   commit 1a89c2c64bb2eff79c09806f484f25eba6cd9829
|\  Merge: 48cfe32 622730c
| | Author: spam ham
| | Date:   Fri Apr 25 16:16:31 2014 +0900
| | 
| |     Merge branch 'topic'
| |   
| * commit 622730cac98bcbdfa65c6a8e3bf396c9d7411efb
| | Author: spam ham
| | Date:   Fri Apr 25 15:55:48 2014 +0900
| | 
| |     edit master_file1 by topci branch
| |   
| * commit cb6981979432a82be38161897527987ae285fdde
|/  Author: spam ham
|   Date:   Fri Apr 25 15:52:42 2014 +0900
|   
|       add topic_file1
|  
* commit 48cfe32d78c91ee66e049d639e81f9de5589ffc5
| Author: spam ham
| Date:   Fri Apr 25 15:54:40 2014 +0900
| 
|     edit master_file1 by master branch
|  
* commit af5b2b29d575cb617cafa0408edf94fe26cd6997
  Author: spam ham
  Date:   Fri Apr 25 15:52:17 2014 +0900
  
      add master_file1
```

masterブランチの作業ツリーにあるファイルを確認する

```bash
$ ls                                                      
master_file1  topic_file1

$ cat master_file1 
* master branch
* topic branch
```