2015-12-22 7 views
6

これはm1は枝devオンなぜマージ競合が発生するのですか? I場合

L1 

を含むファイル、私のgitリポジトリブランチmaster

enter image description here

の初期スナップショットだった、ファイルm1

L1 
L2 

が含まれています合併しようe devからmasterに変更すると、競合が発生します。

$ git checkout master 
Switched to branch 'master' 

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

$ git diff 
diff --cc m1 
index 078f94b,9f46047..0000000 
--- a/m1 
+++ b/m1 
@@@ -1,1 -1,2 +1,5 @@@ 
    L1 
++<<<<<<< HEAD 
++======= 
+ L2 
++>>>>>>> dev 

私はmasterm1の2行目を変更しなかったが、それはどのように紛争が生じたのか?ファイルの実際の内容を確認し、これはホワイトスペースによって引き起こされている場合を確認するために

:ブランチdev

$ git checkout dev 
Switched to branch 'dev' 

$ xxd m1 
0000000: 4c31 0a4c 320a       L1.L2. 

でブランチで

master

git branch 
    dev 
* master 

$ xxd m1 
0000000: 4c31 0a         L1. 

ここですスクリプト私はこのレポを作成するために使用しました。

#!/bin/bash 

mkdir git_demo 
cd git_demo 
git init 

touch m1 
git add . 
git commit -m "Added file: m1" 
# sleep is needed, otherwise a different repo is being created, probably because of *some* filesystem issue! 
sleep 1 

git branch dev 
echo L1 >> m1 
git add . 
git commit -m "Added line L1 to m1" 
# sleep is needed, otherwise a different repo is being created, probably because of *some* filesystem issue! 
sleep 1 

git checkout dev 
echo L1 >> m1 
git add . 
git commit -m "Added line L1 to m1" 
# sleep is needed, otherwise a different repo is being created, probably because of *some* filesystem issue! 
sleep 1 

echo L2 >> m1 
git add . 
git commit -m "Added line L2 to m1" 
# sleep is needed, otherwise a different repo is being created, probably because of *some* filesystem issue! 

gitg --all 
git checkout master 
git merge dev 
+0

ファイルの最終行に多分 "End of File"チャートがありますか? – Geoffroy

+0

私はそうは思わない。更新された投稿の最後を見てください。 –

+0

あなたのフローは、早送りマージの完璧な例です。本当に変です。レポを作成してから正確な手順を投稿できますか? – Maroun

答えて

2

答えはどのmerge-baseは、2本の枝のコミットがないため競合があるということです。

ここでは、より少ないステップで問題を生成する方法を示します。
あなたは、彼らが同じ木に

[enter image description here]

enter image description here

を共有していないことをここで見ることができます

enter image description here

(孤児の分岐はどの歴のない枝である)孤児ブランチを作成します。

enter image description here

+0

アーカイブを解凍して 'git status'を実行しましたか? –

+0

うん、解凍(Unix)して、あなたは私がそこに行くのを見ることができます。私はすぐに狩りをするいくつかの隠されたキャラクターがあります:-) – CodeWizard

+0

このファイルでstashが動作していない、何か変なことがあります。 – CodeWizard

0

これは、再作成するのは簡単です:

% git init                                                  [8:33:13] 
Initialized empty Git repository in /home/martin/tmp/gitte/.git/ 
% touch m1                                                  [8:33:16] 
% git add m1                                                  [8:33:40] 
% git commit -m "Added file: m1"                                             [8:33:48] 
[master (root-commit) 72a9740] Added file: m1 
1 file changed, 0 insertions(+), 0 deletions(-) 
create mode 100644 m1 
% git checkout -b dev                                               [8:34:05] 
Switched to a new branch 'dev' 
% echo L1 >> m1                                                 [8:34:08] 
% git commit -am "Added line L1 to file m1"                                          [8:34:29] 
[dev b16538c] Added line L1 to file m1 
1 file changed, 1 insertion(+) 
% git checkout master                                                [8:34:33] 
Switched to branch 'master' 
% echo L1 >> m1                                                 [8:34:38] 
% git commit -am "Added line L1 to file m1"                                          [8:34:46] 
[master 7b952c8] Added line L1 to file m1 
1 file changed, 1 insertion(+)                                     [8:35:59] 
HEAD is now at 7b952c8 Added line L1 to file m1 
% gitk                                                   [8:36:04] 
% echo L2 >> m1                                                                                                    [8:36:28] 
% git commit -am "Added line L2 to file m1"                                          [8:36:28] 
[master f336d77] Added line L2 to file m1 
1 file changed, 1 insertion(+) 
% git merge dev # merge conflict! 

両方のファイルで行2が異なるため、問題が発生します。あなたのマスターブランチでは、2行目は単に「EOF」であり、devブランチ2行目では「L2」です。

+0

本当ですか?両方のブランチの 'm1'の' xxd'の出力を見ると、 '0a'は改行文字として表示されます。どちらのバージョンのファイルにも別のEOFはありません。 –

+0

元の投稿の 'xxd'出力を確認してください。 –

+0

技術的にはEOF文字がないので、私は答えを明確にしました。しかし、マージ競合が#2行目にあることがはっきりと分かります。ファイルが一度EOFとみなされた場所はL2になり、Gitはこれを競合と見なします。 –

1

共通の祖先が空であるためです。

マスターでは空のファイルに1行追加しました。 devブランチでは、空のファイルに2行追加しました。

いずれかの行が共通していても問題ありません。どちらの側を取るかを選択する必要があります。 1つのラインを持つ側または2を有する側。

+0

この議論から、gitの「マージ」動作は、ベテランユーザーの間でさえも、大部分が間違っていることがわかります。非常に多くの矛盾する理論!しかし、3ウェイマージがどのように状況を改善するかはまだ分かりません。私はgitが 'dev'-' lancestor'の間に 'master'と' lancestor'と 'L2'の間で変化を検出してはならないと思いました。後者は以前のものを支配すべきです。同じ行に変更があった場合にのみ競合が発生すべきですか? –

+0

しかし、マスターと祖先の間に変更があります。先祖は空のファイルです。祖先がマスターと同一であれば、あなたは正しいでしょう。 –

+0

3ウェイマージは、(a)祖先がマージされるバージョンと異なる場合、(b)ファイルの同じ行に変更がない場合、正しく処理されませんか? –

関連する問題