2015-12-22 1 views
6

Это был первоначальный снимок моего мерзавца хранилищаПочему это приводит к конфликту слияния?

enter image description here

На ветке master, файл m1 содержит

L1 

на ветви dev, файл 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 

Хотя я не изменял линии 2 из m1 в master, как же это приводит к конфликту?

Чтобы проверить фактическое содержимое файла и быть уверенным, если это вызвано белыми пространствами:

На ветке master

git branch 
    dev 
* master 

$ xxd m1 
0000000: 4c31 0a         L1. 

На ветке dev

$ git checkout dev 
Switched to branch 'dev' 

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

Вот сценарий, который я использовал для создания этого репо.

#!/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

Последняя строка файла, возможно, у вас будет символ «Конец файла»? – Geoffroy

+0

Я так не думаю. Пожалуйста, взгляните на конец моего обновленного сообщения. –

+0

Ваш поток - прекрасный пример быстрого слияния, это действительно странно. Можете ли вы отправить точные инструкции, так как вы создали репо? – Maroun

ответ

2

Ответ в том, что существует конфликт , потому что нет никакого merge-base совершить для 2 филиала.

Вот как создать проблему за меньшее количество шагов.
Создать сиротский филиал (Orphan филиал является филиалом без истории)

enter image description here

Здесь можно увидеть, что они не разделяют то же самое дерево

[enter image description here]

enter image description here

enter image description here

+0

Вы просто разархивировали архив и выполнили 'git status'? –

+0

Yep, unziped (Unix), и вы можете видеть, что я там получаю. Есть какой-то скрытый персонаж, который я скоро буду охотиться :-) – CodeWizard

+0

Даже сбой не работает, что-то странное в этом файле. – 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

Вы уверены? Если вы видите вывод из 'xxd' на' m1' для обоих ветвей, то символ «0a» будет присутствовать в символе новой строки. В любой из версий файла нет отдельного EOF. –

+0

Пожалуйста, проверьте вывод 'xxd' в моем исходном сообщении. –

+0

технически нет символа EOF, поэтому я уточнил свой ответ. Однако вы можете четко видеть, что конфликт слияния находится в строке # 2. Если файл когда-то считался EOF, теперь L2, и Git видит это как конфликт. –

1

Поскольку общий предок пуст.

В мастере вы добавили одну строку в пустой файл. В ветке dev вы добавили две строки в пустой файл.

Не имеет значения, что одна из линий является общей, вы должны выбрать, какую сторону вы хотите принять; сторона с одной линией или сторона с двумя.

+0

Из этого обсуждения я вижу, что поведение git 'merge' по-прежнему в значительной степени неверно понимается, даже среди пользователей-ветеранов. Так много противоречивых теорий! Тем не менее, я до сих пор не могу понять, как слияние 3-х сторон улучшает ситуацию. Я думал, что git должен обнаруживать изменения между 'master'-'ancestor' и' L2' между 'dev'-'ancestor'. Позже должно доминировать раньше. Разве конфликт не возникает только тогда, когда есть изменения в одной строке? –

+0

Но между мастером и предком происходит изменение. Предки - пустой файл. Если бы предок был бы идентичен хозяину, тогда вы были бы правы. –

+0

Не git 3-way merge правильно обрабатывать, когда (a) предок отличается от обеих версий, подлежащих объединению, и (б) никаких изменений в одной строке файла? –