shop.oreilly.com
Merges
git merge
- 単一リポジトリ内の2つ以上のブランチを統合する
- 多くの場合2つ
- コンフリクト
- 同一ファイルの同一行の変更が競合
- 発生したら、"unmerged"としてインデックスにマークされる
- 解消は開発者に委ねられる
Merge Examples
git checkout branch
git merge other_branch
Preparing for a Merge
- cleanな状態で始めたほうがいいよ
- clean working directory
- clean index
- 【補】v2.17.1で、cleanじゃないとそもそもmergeできない感じだった
Merging Two Branches
git log --branches --graph --oneline
* 3b21657 (alternate) Add alternate's line 4
| * 1cc6004 (HEAD -> master) Another file
|/
* a1225b9 Initial 3 line file
git diff master alternate
diff --git a/file b/file
index fe999ef..a3c4be1 100644
--- a/file
+++ b/file
@@ -1,3 +1,4 @@
Line 1 Stuff
Line 2 Stuff
Line 3 Stuff
+Line 4 alternate stuff
diff --git a/other_file b/other_file
deleted file mode 100644
index eaeeeba..0000000
--- a/other_file
+++ /dev/null
@@ -1 +0,0 @@
-Here is stuff on another file!
git merge alternate
Merge made by the 'recursive' strategy.
file | 1 +
1 file changed, 1 insertion(+)
git log --graph --pretty=oneline --abbrev-commit
* 7a79684 (HEAD -> master) Merge branch 'alternate'
|\
| * 3b21657 (alternate) Add alternate's line 4
* | 1cc6004 Another file
|/
* a1225b9 Initial 3 line file
git merge other_branch
は、「今いるブランチにother_branch
をマージする」の意
- 今いるブランチしか影響を受けない
- この操作ではalternateブランチは影響を受けていない
A Merge with a Conflict
git show-branch
* [alternate] Add alternate line 5 and 6
! [master] Add line 5 and 6
--
* [alternate] Add alternate line 5 and 6
+ [master] Add line 5 and 6
*+ [alternate^] Add alternate's line 4
- 5,6行目がコンフリクト
- master: line5,6追加
- alternate: alternate line5,6追加
git diff master alternate
diff --git a/file b/file
index c063061..1a7b51b 100644
--- a/file
+++ b/file
@@ -2,5 +2,5 @@ Line 1 Stuff
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
-Line 5 stuff
-Line 6 stuff
+Line 5 alternate stuff
+Line 6 alternate stuff
diff --git a/other_file b/other_file
deleted file mode 100644
index eaeeeba..0000000
--- a/other_file
+++ /dev/null
@@ -1 +0,0 @@
-Here is stuff on another file!
git checkout master
git merge alternate
Auto-merging file
CONFLICT (content): Merge conflict in file
Automatic merge failed; fix conflicts and then commit the result.
git diff
diff --cc file
index c063061,1a7b51b..0000000
--- a/file
+++ b/file
@@@ -2,5 -2,5 +2,10 @@@ Line 1 Stuf
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
++<<<<<<< HEAD
+Line 5 stuff
+Line 6 stuff
++=======
+ Line 5 alternate stuff
+ Line 6 alternate stuff
++>>>>>>> alternate
- コンフリクトをどう解消するかは開発者次第
- 今回はこうした
(編集)
git add file
git diff --cached
diff --git a/file b/file
index c063061..89e2b8f 100644
--- a/file
+++ b/file
@@ -3,4 +3,4 @@ Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
Line 5 stuff
-Line 6 stuff
+Line 6 alternate stuff
git commit
するとマージコミットのテンプレートメッセージがEDITORで開く
Merge branch 'alternate'
# Conflicts:
# file
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
# .git/MERGE_HEAD
# and try again.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
# modified: file
#
* ffb7c83 (HEAD -> master) Merge branch 'alternate'
|\
| * 152d410 (alternate) Add alternate line 5 and 6
* | bf387d7 Add line 5 and 6
* | 7a79684 Merge branch 'alternate'
|\ \
| |/
| * 3b21657 Add alternate's line 4
* | 1cc6004 Another file
|/
* a1225b9 Initial 3 line file
Working with Merge Conflicts
Locating Conflicted Files
- git statusでコンフリクトが発生しているファイルを特定できる
git status
On branch tmp
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: file
no changes added to commit (use "git add" and/or "git commit -a")
- git ls-files -u でblobを特定できる
git ls-files -u
100644 a3c4be15bb92e24db3cc4a2db0aa889148a93afe 1 file
100644 c06306161c8c2bd4a16da3f6a3e7e130b9fcecca 2 file
100644 1a7b51bee6459775eb9f30df455ea327fe0d99fe 3 file
git cat-file -p a3c4be15
git cat-file -p c0630616
git cat-file -p 1a7b51be
Line 1 Stuff
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
Line 1 Stuff
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
Line 5 stuff
Line 6 stuff
Line 1 Stuff
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
Line 5 alternate stuff
Line 6 alternate stuff
git diff
diff --cc file
index c063061,1a7b51b..0000000
--- a/file
+++ b/file
@@@ -2,5 -2,5 +2,10 @@@ Line 1 Stuf
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
++<<<<<<< HEAD
+Line 5 stuff
+Line 6 stuff
++=======
+ Line 5 alternate stuff
+ Line 6 alternate stuff
++>>>>>>> alternate
Inspecting Conflicts
>>>>>>>
, =======
, <<<<<<<
は人間向けであってプログラム向けではない
git diff with conflicts
git diff
git diff --ours
git diff --theirs
git diff --base
diff --cc file
index c063061,1a7b51b..0000000
--- a/file
+++ b/file
@@@ -2,5 -2,5 +2,10 @@@ Line 1 Stuf
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
++<<<<<<< HEAD
+Line 5 stuff
+Line 6 stuff
++=======
+ Line 5 alternate stuff
+ Line 6 alternate stuff
++>>>>>>> alternate
* Unmerged path file
diff --git a/file b/file
index c063061..a5e02b0 100644
--- a/file
+++ b/file
@@ -2,5 +2,10 @@ Line 1 Stuff
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
+<<<<<<< HEAD
Line 5 stuff
Line 6 stuff
+=======
+Line 5 alternate stuff
+Line 6 alternate stuff
+>>>>>>> alternate
* Unmerged path file
diff --git a/file b/file
index 1a7b51b..a5e02b0 100644
--- a/file
+++ b/file
@@ -2,5 +2,10 @@ Line 1 Stuff
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
+<<<<<<< HEAD
+Line 5 stuff
+Line 6 stuff
+=======
Line 5 alternate stuff
Line 6 alternate stuff
+>>>>>>> alternate
* Unmerged path file
diff --git a/file b/file
index a3c4be1..a5e02b0 100644
--- a/file
+++ b/file
@@ -2,3 +2,10 @@ Line 1 Stuff
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
+<<<<<<< HEAD
+Line 5 stuff
+Line 6 stuff
+=======
+Line 5 alternate stuff
+Line 6 alternate stuff
+>>>>>>> alternate
git log with conflicts
git log --merge --left-right -p
commit > 152d410b862f8f74966ed4b622a58704af67b51f
Author: Daiki Horiyama <xxxxxxxxx@gmail.com>
Date: Sun Nov 24 16:04:36 2019 +0900
Add alternate line 5 and 6
diff --git a/file b/file
index a3c4be1..1a7b51b 100644
--- a/file
+++ b/file
@@ -2,3 +2,5 @@ Line 1 Stuff
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
+Line 5 alternate stuff
+Line 6 alternate stuff
commit < bf387d7ce60288c102df6566b37d07d0679b99e4
Author: Daiki Horiyama <xxxxxxxxx@gmail.com>
Date: Sun Nov 24 15:57:00 2019 +0900
Add line 5 and 6
diff --git a/file b/file
index a3c4be1..c063061 100644
--- a/file
+++ b/file
@@ -2,3 +2,5 @@ Line 1 Stuff
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
+Line 5 stuff
+Line 6 stuff
- oursとtheirsそれぞれについての情報が得られる
- オプション解説
- マージの苦痛を和らげるためには、小さなコミットをこまめにマージして
How Git Keeps Track of Conflicts
.git/MERGE_HEAD
.git/MERGE_MSG
- インデックス
- base, ours, theirsの3つ保持する
git ls-files -u
で3つ出てきたやつ
- 作業ディレクトリ
>>>>>>>
等のマーカー付きのファイルはインデックスではなく作業ディレクトリにある
- だから
--cached
なしのgit diff
で差分を表示できる
git diff
で、インデックス上の別バージョンのファイルの比較を行うことができる
- 1: base
- 2: ours
- 3: theirs
git diff :2:file :3:file
diff --git a/file b/file
index c063061..1a7b51b 100644
--- a/file
+++ b/file
@@ -2,5 +2,5 @@ Line 1 Stuff
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
-Line 5 stuff
-Line 6 stuff
+Line 5 alternate stuff
+Line 6 alternate stuff
- コンフリクト解消のコンテキストにおいて、
git checkout --ours/--theirs
で一方の変更を受け入れられる
cat file
Line 1 Stuff
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
<<<<<<< HEAD
Line 5 stuff
Line 6 stuff
=======
Line 5 alternate stuff
Line 6 alternate stuff
>>>>>>> alternate
git checkout --theirs file
cat file
Line 1 Stuff
Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
Line 5 alternate stuff
Line 6 alternate stuff
Finishing Up a Conflict Resolution
git ls-files -s
100644 a3c4be15bb92e24db3cc4a2db0aa889148a93afe 1 file
100644 c06306161c8c2bd4a16da3f6a3e7e130b9fcecca 2 file
100644 1a7b51bee6459775eb9f30df455ea327fe0d99fe 3 file
100644 eaeeeba5973e46152dc758215c7e76dcecfd5f9b 0 other_file
- SHA1とファイル名との間の数字は、ステージング番号
- 1: base
- 2: ours
- 3: thries
- 0: コンフリクトがないことを意味する
git add file
git ls-files -s
100644 1a7b51bee6459775eb9f30df455ea327fe0d99fe 0 file
100644 eaeeeba5973e46152dc758215c7e76dcecfd5f9b 0 other_file
- コンフリクトを解消して
git add
等すると0になる
git commit
(コミットメッセージ編集)
git show
Merge branch 'alternate' into tmp
# Conflicts:
# file
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
# .git/MERGE_HEAD
# and try again.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch tmp
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
# modified: file
#
commit fb21453bd655788150e16cc43c4479ebe0ef2649 (HEAD -> tmp)
Merge: bf387d7 152d410
Author: Daiki Horiyama <xxxxxxxxx@gmail.com>
Date: Sun Nov 24 17:22:49 2019 +0900
Merge branch 'alternate' into tmp
- 通常のコミットとマージコミットの違い
Merge: bf387d7 152d410
- デフォルトコミットメッセージにコンフリクトのあったファイルが記述されている
#
でコメントアウトされている
- マージ後に問題が発生したときはおそらくこのファイルが悪い
- diffはマージ元ブランチとの差分のみ
git checkout master
git diff HEAD^
diff --git a/file b/file
index c063061..89e2b8f 100644
--- a/file
+++ b/file
@@ -3,4 +3,4 @@ Line 2 Stuff
Line 3 Stuff
Line 4 alternate stuff
Line 5 stuff
-Line 6 stuff
+Line 6 alternate stuff
Aborting or Restarting a Merge
git reset --hard HEAD
git reset --hard ORIG_HEAD
- ORIG_HEAD: マージ直後にやっぱりやめる用のref
- working directoryがdirtyな状態でmergeを始めていた場合、その変更分は失われるので注意
- 【補】
git merge --abort
というのもある
英語
- octothorpe
- disparty
- gory detail
- mitigate the pain
- botch