２つのコミット履歴を１つに統合する

２つのコミットを１つに統合するために、rebaseを使います。

```
git rebase -i master~<N>
```

ここではmasterブランチに対して、Nには任意の数字をセット
実際にどのように編集するか見ていきます。

例）first_file, second_file1, second_file2のファイルを持ったリポジトリを作成します。以下の2,3を別々のコミットにするのは冗長なので１つにまとめます。

手順としては、

1. first_fileを新規作成してコミット
2. second_file1を新規作成してコミット
3. second_file2を新規作成してコミット
4. first_fileを編集してコミット

コマンドにすると以下のものになります。

```
#gitの初期化
$ git init
Initialized empty Git repository in /Users/TechMeetMeet/Documents/work/git_work/.git/
$ git config user.email "tech.meetmeet@gmail.com"

#first_fileを作成してコミット
$ cat > first_file
This is a first line.
This is a second line.
^Dで終了
$ git add first_file
$ git commit -m "first commit"
[master (root-commit) 524ead8] first commit
 1 file changed, 3 insertions(+)
 create mode 100644 first_file

#second_file1を作成してコミット
$ cat > second_file1
This file is second file1.
$ git add second_file1
$ git commit -m "second file1 commit"
[master b3e712e] second file1 commit
 1 file changed, 1 insertion(+)
 create mode 100644 second_file1

#second_file2を作成してコミット
$ cat > second_file2
This file is second file2.
$ git add second_file2
$ git commit -m "second file2 commit"
[master a3fd259] second file2 commit
 1 file changed, 1 insertion(+)
 create mode 100644 second_file2

#first_fileを編集してコミット
$ cat >> first_file
This is a third line.
$ git add first_file
$ git commit -m "edit first file"
[master 287611c] edit first file
 1 file changed, 1 insertion(+)

#ブランチ作業履歴を表示
$ git show-branch --more=4
[master] edit first file
[master^] second file2 commit
[master~2] second file1 commit
[master~3] first commit
 ```

２つのコミットを統合する

ここでは2,3の手順が別のコミットとなっているのは冗長なので１つのコミットとしてまとめる

```
$ git rebase -i master~3
```
とするとエディタが開くので

```
pick b3e712e second file1 commit
pick a3fd259 second file2 commit
pick 287611c edit first file

# Rebase 524ead8..287611c onto 524ead8
#
# 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
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
```
となるものを、今回統合したい "file2 commit"の行を編集します。

具体的には、pickという文字列をsquashに変更して保存し直すと、直前のコミットと統合されます。

```
pick b3e712e second file1 commit
squash a3fd259 second file2 commit
pick 287611c edit first file

# Rebase 524ead8..287611c onto 524ead8
#
# 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
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
```

こちらの変更をして保存すると、再度エディタが開きます。ここでは統合したコミットのメッセージを設定します。

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

second file1 commit

# This is the 2nd commit message:

second file2 commit

# 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.
# You are currently editing a commit during a rebase.
#
# Changes to be committed:
#   (use "git reset HEAD^1 <file>..." to unstage)
#
#       new file:   second_file1
#       new file:   second_file2
#
```

となっているものの、

```
# This is a combination of 2 commits.
```

の下に、コミットメッセージを挿入して保存すればOKです。

```
# This is a combination of 2 commits.
second file1, file2 commit

# The first commit's message is:

second file1 commit

# This is the 2nd commit message:

second file2 commit

# 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.
# You are currently editing a commit during a rebase.
#
# Changes to be committed:
#   (use "git reset HEAD^1 <file>..." to unstage)
#
#       new file:   second_file1
#       new file:   second_file2
#
```

これで２つのコミットの統合作業は完了です。

 

最後に、ブランチツリーを表示して正しくコミットが統合されているか確認します。

```
$ git show-branch --more=4
[master] edit first file
[master^] second file1, file2 commit
[master~2] first commit
```

これで成功です。