Git初心者のメモ その2：commitしてみた。

以前書いたGitに関する記事：[git初心者のメモ](http://qiita.com/y_ito/items/7c99dd9c78119d428804)

#やりたいこと
まずファイルを作成して最初のコミットをする（コミット0）。

```sample.php
<?php

exit;
```

次にコードを足して保存し、コミットしする（コミット1）。

```sample.php
<?php

print "helo" . PHP_EOL;

exit;
```

さらにコードを足して保存し、コミットしする（コミット2）。

```sample.php
<?php

print "helo" . PHP_EOL;
print "bye" . PHP_EOL;

exit;
```

これで完了。と思ったら、"hello"と書いたつもりが"helo"になっていた。修正してコミットする（コミット3）。

```sample.php
<?php

print "hello" . PHP_EOL;
print "bye" . PHP_EOL;

exit;
```

間違ってしまった過去を消したいので、コミット1とコミット3をまとめる。

ここまでやる。


#実践

gitのバージョンは2.10.0。OSはWindows 7 64bit。git bash上で実行した。

リポジトリを作成する。

```shell-session
y_ito@note MINGW64 /c/tmp/git_test
$ git init
Initialized empty Git repository in C:/tmp/tmp/git_test_01/.git/

```

ファイルを作成してコミットする（コミット0）。

```shell-session:
y_ito@note MINGW64 /c/tmp/git_test (master)
$ git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        sample.php

nothing added to commit but untracked files present (use "git add" to track)

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git add .
warning: CRLF will be replaced by LF in sample.php.
The file will have its original line endings in your working directory.

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   sample.php


y_ito@note MINGW64 /c/tmp/git_test (master)
$ git commit
[master (root-commit) ca01723] first commit
 1 file changed, 3 insertions(+)
 create mode 100644 sample.php

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git log
commit ca0172381770e64161902e1a96f2e98269f7d980
Author: yito <yito@moge.jp>
Date:   Sun Nov 13 21:28:18 2016 +0900

    first commit

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git status
On branch master
nothing to commit, working tree clean

```

コードを追加してコミットする（コミット1）。

```shell-session:
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   sample.php

no changes added to commit (use "git add" and/or "git commit -a")

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git add .
warning: CRLF will be replaced by LF in sample.php.
The file will have its original line endings in your working directory.

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   sample.php


y_ito@note MINGW64 /c/tmp/git_test (master)
$ git commit
[master 333b87e] add "hello"
 1 file changed, 2 insertions(+)

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git log
commit 333b87e900da570d336c86ee06ef8188842a4e72
Author: yito <yito@moge.jp>
Date:   Sun Nov 13 21:29:41 2016 +0900

    add "hello"

commit ca0172381770e64161902e1a96f2e98269f7d980
Author: yito <yito@moge.jp>
Date:   Sun Nov 13 21:28:18 2016 +0900

    first commit

```

コードを追加してコミットする（コミット2）。途中でコミット1と現在の内容の差分を見ている。

```shell-session:
y_ito@note MINGW64 /c/tmp/git_test (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   sample.php

no changes added to commit (use "git add" and/or "git commit -a")

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git diff
diff --git a/sample.php b/sample.php
index 84ea558..fd9256e 100644
--- a/sample.php
+++ b/sample.php
@@ -1,5 +1,6 @@
 <?php

 print "helo" . PHP_EOL;
+print "bye" . PHP_EOL;

 exit;
warning: CRLF will be replaced by LF in sample.php.
The file will have its original line endings in your working directory.

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git diff -- sample.php
diff --git a/sample.php b/sample.php
index 84ea558..fd9256e 100644
--- a/sample.php
+++ b/sample.php
@@ -1,5 +1,6 @@
 <?php

 print "helo" . PHP_EOL;
+print "bye" . PHP_EOL;

 exit;
warning: CRLF will be replaced by LF in sample.php.
The file will have its original line endings in your working directory.

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git add .
warning: CRLF will be replaced by LF in sample.php.
The file will have its original line endings in your working directory.

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   sample.php


y_ito@note MINGW64 /c/tmp/git_test (master)
$ git diff --cached
diff --git a/sample.php b/sample.php
index 84ea558..fd9256e 100644
--- a/sample.php
+++ b/sample.php
@@ -1,5 +1,6 @@
 <?php

 print "helo" . PHP_EOL;
+print "bye" . PHP_EOL;

 exit;

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git commit
[master 91fc04d] add "bye"
 1 file changed, 1 insertion(+)

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git log
commit 91fc04dbe5d230ba01b208b8aceb32e1d8f4f15e
Author: yito <yito@moge.jp>
Date:   Sun Nov 13 21:30:59 2016 +0900

    add "bye"

commit 333b87e900da570d336c86ee06ef8188842a4e72
Author: yito <yito@moge.jp>
Date:   Sun Nov 13 21:29:41 2016 +0900

    add "hello"

commit ca0172381770e64161902e1a96f2e98269f7d980
Author: yito <yito@moge.jp>
Date:   Sun Nov 13 21:28:18 2016 +0900

    first commit

```

"helo" を "hello" に修正してコミットする（コミット3）。

```shell-session:
y_ito@note MINGW64 /c/tmp/git_test (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   sample.php

no changes added to commit (use "git add" and/or "git commit -a")

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git add .
warning: CRLF will be replaced by LF in sample.php.
The file will have its original line endings in your working directory.

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   sample.php


y_ito@note MINGW64 /c/tmp/git_test (master)
$ git commit
[master c085713] modify "helo" to "hello"
 1 file changed, 1 insertion(+), 1 deletion(-)

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git log
commit c0857136136bcb119ec6373a894302f59fbcf307
Author: yito <yito@moge.jp>
Date:   Sun Nov 13 21:32:32 2016 +0900

    modify "helo" to "hello"

commit 91fc04dbe5d230ba01b208b8aceb32e1d8f4f15e
Author: yito <yito@moge.jp>
Date:   Sun Nov 13 21:30:59 2016 +0900

    add "bye"

commit 333b87e900da570d336c86ee06ef8188842a4e72
Author: yito <yito@moge.jp>
Date:   Sun Nov 13 21:29:41 2016 +0900

    add "hello"

commit ca0172381770e64161902e1a96f2e98269f7d980
Author: yito <yito@moge.jp>
Date:   Sun Nov 13 21:28:18 2016 +0900

    first commit

```

コミット1とコミット3をまとめる。`git rebase -i` を実行する。

```shell-session:
y_ito@note MINGW64 /c/tmp/git_test (master)
$ git log --oneline
c085713 modify "helo" to "hello"
91fc04d add "bye"
333b87e add "hello"
ca01723 first commit

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git rebase -i ca01723
```

`git rebase -i` を実行するとエディタが起動して下記の画面が出る。

```text:インタラクティブなrebaseの画面（編集前）
pick 333b87e add "hello"
pick 91fc04d add "bye"
pick c085713 modify "helo" to "hello"

# Rebase ca01723..c085713 onto ca01723 (3 commands)
#
# 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
# d, drop = remove commit
#
```

これを下記のように、3行目を1行目の下に移動し、"pick" を "s" に変更して保存する。
"s" はその行のコミットを上の行のコミットにまとめる。

```text:インタラクティブなrebaseの画面（編集後）
pick 333b87e add "hello"
s c085713 modify "helo" to "hello"
pick 91fc04d add "bye"

# Rebase ca01723..c085713 onto ca01723 (3 commands)
#
# 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
# d, drop = remove commit
#
# 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
```

エディタを終了して完了、と思いきや、こんなメッセージが出る。

```shell-session:
y_ito@note MINGW64 /c/tmp/git_test (master)
$ git rebase -i ca01723
Auto-merging sample.php
CONFLICT (content): Merge conflict in sample.php
error: could not apply c085713... modify "helo" to "hello"

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

Could not apply c085713... modify "helo" to "hello"

```

コンフリクトしたらしい。
ここから先、ほぼ何をやっているかわからない。
`git status` で状況を確認。

```shell-session:
$ git status
interactive rebase in progress; onto ca01723
Last commands done (2 commands done):
   pick 333b87e add "hello"
   s c085713 modify "helo" to "hello"
Next command to do (1 remaining command):
   pick 91fc04d add "bye"
  (use "git rebase --edit-todo" to view and edit)
You are currently rebasing branch 'master' on 'ca01723'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git reset HEAD <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

        both modified:   sample.php

no changes added to commit (use "git add" and/or "git commit -a")

y_ito@note MINGW64 /c/tmp/git_test (master|REBASE-i 2/3)
$ git diff
diff --cc sample.php
index 84ea558,3378eec..0000000
--- a/sample.php
+++ b/sample.php
@@@ -1,5 -1,6 +1,10 @@@
  <?php

++<<<<<<< HEAD
 +print "helo" . PHP_EOL;
++=======
+ print "hello" . PHP_EOL;
+ print "bye" . PHP_EOL;
++>>>>>>> c085713... modify "helo" to "hello"

  exit;
```

コンフリクトを解消する。
エディタでファイルを開くとこうなっている。

```php:sample.php（編集前）
<?php

<<<<<<< HEAD
print "helo" . PHP_EOL;
=======
print "hello" . PHP_EOL;
print "bye" . PHP_EOL;
>>>>>>> c085713... modify "helo" to "hello"

exit;
```

下記のように編集して保存する。

```php:sample.php（編集後）
<?php

print "hello" . PHP_EOL;

exit;
```

`git add` してから、さきほどの `git status` のメッセージの中にあった `git rebase --edit-todo` を実行してみる。

```shell-session:
y_ito@note MINGW64 /c/tmp/git_test (master|REBASE-i 2/3)
$ git add .

y_ito@note MINGW64 /c/tmp/git_test (master|REBASE-i 2/3)
$ git status
interactive rebase in progress; onto ca01723
Last commands done (2 commands done):
   pick 333b87e add "hello"
   s c085713 modify "helo" to "hello"
Next command to do (1 remaining command):
   pick 91fc04d add "bye"
  (use "git rebase --edit-todo" to view and edit)
You are currently rebasing branch 'master' on 'ca01723'.
  (all conflicts fixed: run "git rebase --continue")

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   sample.php


y_ito@note MINGW64 /c/tmp/git_test (master|REBASE-i 2/3)
$ git diff

y_ito@note MINGW64 /c/tmp/git_test (master|REBASE-i 2/3)
$ git rebase --edit-todo
```

エディタが立ち上がって以下のように表示される。そのまま保存してエディタを終了する。

```text:インタラクティブなrebaseの画面
pick 91fc04d add "bye"
#
# 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
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# You are editing the todo file of an ongoing interactive rebase.
# To continue rebase after editing, run:
#     git rebase --continue
#
```

`git status` とすると、何も変わっていない？ `git diff` は何も表示しなくなっているが。

```shell-session:
y_ito@note MINGW64 /c/tmp/git_test (master|REBASE-i 2/3)
$ git status
interactive rebase in progress; onto ca01723
Last commands done (2 commands done):
   pick 333b87e add "hello"
   s c085713 modify "helo" to "hello"
Next command to do (1 remaining command):
   pick 91fc04d add "bye"
  (use "git rebase --edit-todo" to view and edit)
You are currently rebasing branch 'master' on 'ca01723'.
  (all conflicts fixed: run "git rebase --continue")

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   sample.php


y_ito@note MINGW64 /c/tmp/git_test (master|REBASE-i 2/3)
$ git diff

```

`git rebase --continue` を実行する。

```shell-session:
y_ito@note MINGW64 /c/tmp/git_test (master|REBASE-i 2/3)
$ git rebase --continue
```

エディタが起動し以下のように表示される。

```text:コミットメッセージの編集（編集前）
# This is a combination of 2 commits.
# The first commit's message is:

add "hello"

# This is the commit message #2:

modify "helo" to "hello"

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Sun Nov 13 21:29:41 2016 +0900
#
# interactive rebase in progress; onto ca01723
# Last commands done (2 commands done):
#    pick 333b87e add "hello"
#    s c085713 modify "helo" to "hello"
# Next command to do (1 remaining command):
#    pick 91fc04d add "bye"
# You are currently rebasing branch 'master' on 'ca01723'.
#
# Changes to be committed:
#       modified:   sample.php
#
```

これを下記のように編集して保存する。

```text:コミットメッセージの編集（編集後）
# This is a combination of 2 commits.
# The first commit's message is:

add "hello"


# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Sun Nov 13 21:29:41 2016 +0900
#
# interactive rebase in progress; onto ca01723
# Last commands done (2 commands done):
#    pick 333b87e add "hello"
#    s c085713 modify "helo" to "hello"
# Next command to do (1 remaining command):
#    pick 91fc04d add "bye"
# You are currently rebasing branch 'master' on 'ca01723'.
#
# Changes to be committed:
#       modified:   sample.php
#
```

エディタを終了すると下記のように表示される。

```
y_ito@note MINGW64 /c/tmp/git_test (master|REBASE-i 2/3)
$ git rebase --continue
[detached HEAD 71bcc37] add "hello"
 Date: Sun Nov 13 21:29:41 2016 +0900
 1 file changed, 2 insertions(+)
Auto-merging sample.php
CONFLICT (content): Merge conflict in sample.php
error: could not apply 91fc04d... add "bye"

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

Could not apply 91fc04d... add "bye"

y_ito@note MINGW64 /c/tmp/git_test (master|REBASE-i 3/3)
```

`git status` で状況を見るとまだコンフリクトしているようだ。

```
$ git status
interactive rebase in progress; onto ca01723
Last commands done (3 commands done):
   s c085713 modify "helo" to "hello"
   pick 91fc04d add "bye"
  (see more in file .git/rebase-merge/done)
No commands remaining.
You are currently rebasing branch 'master' on 'ca01723'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git reset HEAD <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

        both modified:   sample.php

no changes added to commit (use "git add" and/or "git commit -a")

y_ito@note MINGW64 /c/tmp/git_test (master|REBASE-i 3/3)
$ git diff
diff --cc sample.php
index 86aae99,fd9256e..0000000
--- a/sample.php
+++ b/sample.php
@@@ -1,5 -1,6 +1,10 @@@
  <?php

++<<<<<<< HEAD
 +print "hello" . PHP_EOL;
++=======
+ print "helo" . PHP_EOL;
+ print "bye" . PHP_EOL;
++>>>>>>> 91fc04d... add "bye"

  exit;

```

コンフリクトを解消する。
エディタでソースファイルを開くと下記のようになっている。

```
<?php

<<<<<<< HEAD
print "hello" . PHP_EOL;
=======
print "helo" . PHP_EOL;
print "bye" . PHP_EOL;
>>>>>>> 91fc04d... add "bye"

exit;
```

下記のように編集する。

```
<?php

print "hello" . PHP_EOL;
print "bye" . PHP_EOL;

exit;
```

`git add` する。

```
y_ito@note MINGW64 /c/tmp/git_test (master|REBASE-i 3/3)
$ git add .

y_ito@note MINGW64 /c/tmp/git_test (master|REBASE-i 3/3)
$ git status
interactive rebase in progress; onto ca01723
Last commands done (3 commands done):
   s c085713 modify "helo" to "hello"
   pick 91fc04d add "bye"
  (see more in file .git/rebase-merge/done)
No commands remaining.
You are currently rebasing branch 'master' on 'ca01723'.
  (all conflicts fixed: run "git rebase --continue")

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   sample.php

```

再度 `git continue` を実行する。

```
$ git rebase --continue
[detached HEAD 59700e5] add "bye"
 1 file changed, 1 insertion(+)
Successfully rebased and updated refs/heads/master.

```



```text:コミットメッセージの編集（変更しないでこのまま保存）
add "bye"

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# interactive rebase in progress; onto ca01723
# Last commands done (3 commands done):
#    s c085713 modify "helo" to "hello"
#    pick 91fc04d add "bye"
# No commands remaining.
# You are currently rebasing branch 'master' on 'ca01723'.
#
# Changes to be committed:
#       modified:   sample.php
#
```

これで完了したっぽい。
`git log`,'git show',`git diff` で確認する。
最初のコミット以外はリビジョンが変わっている。

```
$ git log
commit 59700e5779eb4939b990f1f91cb9a3b7c6ba10fe
Author: yito <yito@moge.jp>
Date:   Sun Nov 13 21:30:59 2016 +0900

    add "bye"

commit 71bcc37923a9d671664e5b14786562b1947588fd
Author: yito <yito@moge.jp>
Date:   Sun Nov 13 21:29:41 2016 +0900

    add "hello"

commit ca0172381770e64161902e1a96f2e98269f7d980
Author: yito <yito@moge.jp>
Date:   Sun Nov 13 21:28:18 2016 +0900

    first commit

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git log --oneline
59700e5 add "bye"
71bcc37 add "hello"
ca01723 first commit

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git show ca01723:sample.php
<?php

exit;

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git show 71bcc37:sample.php
<?php

print "hello" . PHP_EOL;

exit;

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git show 59700e5:sample.php
<?php

print "hello" . PHP_EOL;
print "bye" . PHP_EOL;

exit;

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git diff ca01723..71bcc37 -- sample.php
diff --git a/sample.php b/sample.php
index b66b36e..86aae99 100644
--- a/sample.php
+++ b/sample.php
@@ -1,3 +1,5 @@
 <?php

+print "hello" . PHP_EOL;
+
 exit;

y_ito@note MINGW64 /c/tmp/git_test (master)
$ git diff 71bcc37..59700e5 -- sample.php
diff --git a/sample.php b/sample.php
index 86aae99..3378eec 100644
--- a/sample.php
+++ b/sample.php
@@ -1,5 +1,6 @@
 <?php

 print "hello" . PHP_EOL;
+print "bye" . PHP_EOL;

 exit;

```

#感想

コンフリクトの解消は、正直何をやっているか良く分からない。
`git rebase --edit-todo` はやる必要なかった？
コミットをまとめようと `git rebase -i` してコンフリクトが起きたら、今の自分の知識ではあきらめて `git rebase --abort` とした方がいいかも。