Git octopus порядок слияния нескольких ветвей

у меня была интересная вещь с использованием git, интересно, может ли кто-нибудь объяснить мне это, чтобы я мог лучше понять.

при выполнении слияния нескольких ветвей (A, B),

git merge A B

терпит неудачу как non-fast-forward, пока

git merge B A

хорошо работал. С чего бы это?

1 ответов


предположим, что A является строгим,прямым потомком текущей ветви. Тогда предположим, что B-строгий, прямой ребенок на.

осьминог слияние, которое обрабатывает головы, приведенные в качестве аргументов слева направо, постепенно по отношению к дереву, а независимо по отношению к индексу преуспевает без конфликта, если он пытается применить B, а затем A, но сталкивается с конфликтом, если он делает преобразование.

на git-merge руководство по эксплуатации, раздел СТРАТЕГИИ СЛИЯНИЯ:

octopus
   This resolves cases with more than two heads, but refuses to do a
   complex merge that needs manual resolution.

например:

 ~                 $ git init testdir && cd testdir && echo "This is C" > myfile
 Initialized empty Git repository in /home/huitseeker/testdir/.git/

 ~/testdir         $ git add myfile && git commit -m "C" 
 [master (root-commit) f0c8c82] C
  1 files changed, 1 insertions(+), 0 deletions(-)
  create mode 100644 myfile

 ~/testdir(master) $ git checkout -b "A" && echo "This is A1" > myfile
 Switched to a new branch 'A'
 ~/testdir(A)      $ git commit -m "A1" myfile
 [A ac5b51c] A1
  1 files changed, 1 insertions(+), 1 deletions(-)

 ~/testdir(A)      $ git checkout -b "B" && echo "This is B1" >> myfile
 Switched to a new branch 'B'
 ~/testdir(B)      $ git commit -m "B1" myfile
 [B 5bc838c] B1
  1 files changed, 1 insertions(+), 0 deletions(-)

 ~/testdir(B)      $ git checkout master
 Switched to branch 'master'
 ~/testdir(master) $ git merge B A
 Fast-forwarding to: B
 Already up-to-date with A
 Merge made by octopus.
  myfile |    3 ++-
  1 files changed, 2 insertions(+), 1 deletions(-)

 ~/testdir(master) $ git reset --hard HEAD^^^
 HEAD is now at f0c8c82 C
 ~/testdir(master) $ git merge A B
 Fast-forwarding to: A
 Fast-forwarding to: B
 error: Entry 'myfile' would be overwritten by merge. Cannot merge.
 Merge with strategy octopus failed.

 ~/testdir(master) $ cat myfile
 This is A1

действительно, при быстрой переадресации на A метка master не была выдвинута вперед, хотя дерево.

 ~/testdir(master) $ git status
 # On branch master
 # Changes to be committed:
 #   (use "git reset HEAD <file>..." to unstage)
 #
 #  modified:   myfile
 #

Если, глядя на код того, что делает слияние осьминогов, я выполняю это вручную (см. выше хэши):

 ~/testdir(master) $ git reset --hard f0c8c82
 HEAD is now at f0c8c82 C     
 ~/testdir(master) $ git read-tree -u -m f0c8c82 ac5b51c
 ~/testdir(master) $ git read-tree -u -m f0c8c82 5bc838c
 error: Entry 'myfile' would be overwritten by merge. Cannot merge.

в другую сторону (merge B A), теперь, если вы снова смотрите на код merge-octopus, он пытается обнаружить ветку, которую мы пытаемся добавить, уже в дереве (second case на for loop). Действительно, при слиянии A он видит ac5b51c (a.к. a. Голова а) является общим предком а и В, и прерывается, не делая второго read-tree.

это поведение согласуется со свежей версией git : хотя я указал на V.1.3.1, это все еще происходит с моей версией.

 ~/testdir(master) $ git --version
 git version 1.7.5.4

tl; dr : вы хотите, чтобы ваши ветви слияния осьминога касались отдельных файлов