2018年以降の記事はGitHub Pagesに移行しました

Pro Gitと入門gitでGitの復習 マージ編

前回までのあらすじ

今回はマージから。

参考

マージ

前準備

ここでブランチ用にリポジトリを作りなおした。

$ cat field.html
<h1>僕にその手を汚せというのか</h1>

というファイルを作成し、chapter1というブランチを切る。

$ git branch chapter1

$ git branch
  chapter1
* master

ブランチはこうなるはず。

*master/chapter1/HEAD
↓
↓
○
 

次にchapter2を作成し、ブランチ切り替え。

$ git checkout -b chapter2law chapter1
Switched to a new branch 'chapter2law'

文言を追加し、コミット。

$ cat field.html
<h1>僕にその手を汚せというのか</h1>
<h2>誰も僕を責めることはできない</h2>

$ git commit -a -m "Add chapter2 law route"

ブランチはこうなるはず。chapter2lawに切り替えているのでHEADもこちらへ。

master/chapter1
↓ *chapter2law/HEAD
↓ ↓
↓┌○
○┘
 

同様にchapter3lawも作る。

$ git checkout -b chapter3law chapter2law
Switched to a new branch 'chapter3law'

$ cat field.html
<h1>僕にその手を汚せというのか</h1>
<h2>誰も僕を責めることはできない</h2>
<h3>欺き欺かれて</h3>

$ git commit -a -m "Add chapter3 law route"
master/chapter1
↓ chapter2law
↓ ↓ *chapter3law/HEAD
↓ ↓ ↓
↓┌○─○
○┘
 

ここでchapter1から派生させて、馬鹿な事はやめるんだッ! と新しいブランチを作成。

$ git checkout -b chapter2chaos chapter1
Switched to a new branch 'chapter2chaos'

chapter1を元にcheckout -bしたのでファイルの中身を見るとh1タグしかない状態に戻っている。

$ cat field.html
<h1>僕にその手を汚せというのか</h1>

また文言を追加しコミット。

$ cat field.html
<h1>僕にその手を汚せというのか</h1>
<h2>思いどおりにいかないのが世の中なんて割り切りたくないから</h2>

$ git commit -a -m "Add chapter2 chaos route"
master/chapter1
↓ chapter2law
↓ ↓ chapter3law
↓ ↓ ↓
↓┌○─○
↓│
○┴○
  ↑
  *chapter2chaos/HEAD

この調子でchapter3neutralとchapter3chaosブランチを作る。

$ git checkout -b chapter3neutral chapter2chaos
Switched to a new branch 'chapter3neutral'

$ cat field.html
<h1>僕にその手を汚せというのか</h1>
<h2>思いどおりにいかないのが世の中なんて割り切りたくないから</h2>
<h3>すくいきれないもの</h3>

$ git commit -a -m "Add chapter3 neutral route"

$ git checkout -b chapter3chaos chapter2chaos
Switched to a new branch 'chapter3chaos'

$ cat field.html
<h1>僕にその手を汚せというのか</h1>
<h2>思いどおりにいかないのが世の中なんて割り切りたくないから</h2>
<h3>駆り立てるのは野心と欲望、横たわるのは犬と豚</h3>

$ git commit -a -m "Add chapter3 chaos route"
master/chapter1
↓ chapter2law
↓ ↓ chapter3law
↓ ↓ ↓
↓┌○─○
↓│
○┴○┬○
  ↑│↑
  ↑│chapter3neutral
  ↑└○
  ↑ ↑
  ↑ *chapter3chaos/HEAD
  chapter2chaos

logコマンドで見てみる。あってるかな。

$ git log --graph --date-order --all --date=short -C -M --pretty=format:"%h"\ %ad\ %cn\ %Cgreen%d%Cre
set\ %s
* 2078f0a 2012-03-07 kk_Ataka  (HEAD, chapter3chaos) Add chapter3 chaos route
| * 427a08c 2012-03-07 kk_Ataka  (chapter3neutral) Add chapter3 neutral route
|/
* 416daca 2012-03-07 kk_Ataka  (chapter2chaos) Add chapter2 chaos route
| * 3dc258a 2012-03-07 kk_Ataka  (chapter3law) Add chapter3 law route
| * cae3956 2012-03-07 kk_Ataka  (chapter2law) Add chapter2 law route
|/
* 9d2e5d1 2012-03-07 kk_Ataka  (master, chapter1) typo
* 4e0ebaa 2012-03-07 kk_Ataka  Add chapter 1
* 338a929 2012-03-07 kk_Ataka  First commit
いよいよマージ

最後に今わかれているlaw,chaos,neutralのブランチをchapter4にマージする。まずは久々にmasterブランチに戻る。

$ git checkout master
Switched to branch 'master'

$ cat field.html
<h1>僕にその手を汚せというのか</h1>

merge [branch]コマンドでまずchapter3lawをマージ。

$ git merge chapter3law
Updating 9d2e5d1..3dc258a
Fast-forward
 field.html |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
 
$ cat field.html
<h1>僕にその手を汚せというのか</h1>
<h2>誰も僕を責めることはできない</h2>
<h3>欺き欺かれて</h3>

マージ元のブランチ(master)がマージ先のブランチ(chapter3law)の親である場合、"直接到達できる"という事なので、masterブランチをそのままchapter3lawまですすめられた。

本来は、ここでchapter3lawブランチは削除するらしい(masterにすべてマージされたからもう必要ないであろうということ?)が、記念に残しておく。

次にchaosルートも取り込む。コマンドは同じだが、出力が少し違う。

$ git merge chapter3chaos
Auto-merging field.html
CONFLICT (content): Merge conflict in field.html
Automatic merge failed; fix conflicts and then commit the result.

コンフリクトが起きたようだ。競合を解決してくださいとファイルが編集されるのでステータスも変わる。しかもメッセージもいつもと違う。Unmerged pathとか出る。
いつもの。

$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       README
nothing added to commit but untracked files present (use "git add" to track)

今回の。

$ git status
# On branch master
# Unmerged paths:
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#       both modified:      field.html
#
no changes added to commit (use "git add" and/or "git commit -a")

ファイルを見てみる。

$ cat field.html
<h1>僕にその手を汚せというのか</h1>
<<<<<<< HEAD
<h2>誰も僕を責めることはできない</h2>
<h3>欺き欺かれて</h3>
=======
<h2>思いどおりにいかないのが世の中なんて割り切りたくないから</h2>
<h3>駆り立てるのは野心と欲望、横たわるのは犬と豚</h3>
>>>>>>> chapter3chaos

今マージしたchapter3law=master=HEADとchapter3chaosで競合。とりあえずそのまま追記追記するように。

$ cat field.html
<h1>僕にその手を汚せというのか</h1>
<h2>誰も僕を責めることはできない</h2>
<h3>欺き欺かれて</h3>
<h2>思いどおりにいかないのが世の中なんて割り切りたくないから</h2>
<h3>駆り立てるのは野心と欲望、横たわるのは犬と豚</h3>

最後にニュートラルなんだけど、また競合しそう……。

$ git merge chapter3neutral
Auto-merging field.html
CONFLICT (content): Merge conflict in field.html
Automatic merge failed; fix conflicts and then commit the result.

ああやっぱり。

$ cat field.html
<h1>僕にその手を汚せというのか</h1>
<h2>誰も僕を責めることはできない</h2>
<h3>欺き欺かれて</h3>
<h2>思いどおりにいかないのが世の中なんて割り切りたくないから</h2>
<<<<<<< HEAD
<h3>駆り立てるのは野心と欲望、横たわるのは犬と豚</h3>
=======
<h3>すくいきれないもの</h3>
>>>>>>> chapter3neutral

とりあえず競合を消して最後の文言を。

$ cat field.html
<h1>僕にその手を汚せというのか</h1>
<h2>誰も僕を責めることはできない</h2>
<h3>欺き欺かれて</h3>
<h2>思いどおりにいかないのが世の中なんて割り切りたくないから</h2>
<h3>駆り立てるのは野心と欲望、横たわるのは犬と豚</h3>
<h3>すくいきれないもの</h3>

$ git commit -a -m "Merge conflict"
[master 134d7a8] Merge conflict

$ cat field.html
<h1>僕にその手を汚せというのか</h1>
<h2>誰も僕を責めることはできない</h2>
<h3>欺き欺かれて</h3>
<h2>思いどおりにいかないのが世の中なんて割り切りたくないから</h2>
<h3>駆り立てるのは野心と欲望、横たわるのは犬と豚</h3>
<h3>すくいきれないもの</h3>
<h4>手を取り合って</h4>

$ git commit -a -m "Add chapter4 title"
[master f83bfdb] Add chapter4 title
 1 files changed, 1 insertions(+), 0 deletions(-)

最後にグラフを見てみる。

$ git log --graph --date-order --all --date=short -C -M --pretty=format:"%h"\ %ad\ %cn\ %Cgreen%d%Cre
set\ %s
* f83bfdb 2012-03-07 kk_Ataka  (HEAD, master, chapter4) Add chapter4 title
*   134d7a8 2012-03-07 kk_Ataka  Merge conflict
|\
* | a8e9a29 2012-03-07 kk_Ataka  Merge conflict
* | a1d3f55 2012-03-07 kk_Ataka  Delete conflict
* |   9040fa9 2012-03-07 kk_Ataka  Merge chapter3law in master
|\ \
| * | 2078f0a 2012-03-07 kk_Ataka  (chapter3chaos) Add chapter3 chaos route
| | * 427a08c 2012-03-07 kk_Ataka  (chapter3neutral) Add chapter3 neutral route
| |/
| * 416daca 2012-03-07 kk_Ataka  (chapter2chaos) Add chapter2 chaos route
* | 3dc258a 2012-03-07 kk_Ataka  (chapter3law) Add chapter3 law route
* | cae3956 2012-03-07 kk_Ataka  (chapter2law) Add chapter2 law route
|/
* 9d2e5d1 2012-03-07 kk_Ataka  (chapter1) typo
* 4e0ebaa 2012-03-07 kk_Ataka  Add chapter 1
* 338a929 2012-03-07 kk_Ataka  First commit

こうなってるか。

chapter1
↓ chapter2law
↓ ↓ chapter3law    master/chapter4/HEAD
↓ ↓ ↓        ↓
↓┌○─○───────┐↓
↓│          │↓
○┴○┬○───────┼○
  ↑│↑       │
  ↑│chapter3neutral │
  ↑└○───────┘
  ↑ ↑
  ↑ chapter3chaos
  chapter2chaos

本当は、これをやってみたかったんだけど例が悪すぎて両方コンフリクトしてしまった

# 図 3-16. Git が共通の先祖を自動的に見つけ、ブランチのマージに使用する
$ git checkout master
$ git merge iss53
Merge made by recursive.
README | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

次はリモートブランチとかリベース。