Let's assume that A is a strict, direct child of the current branch. Then assume that B is a strict, direct child of A.
The octopus merge, which processes heads given as arguments from left to right, incrementally with respect to the tree, but independently with respect to the index succeeds without conflict if it tries to apply B and then A, but encounters a conflict if it does the convert.
As per the git-merge
manual, section MERGE STRATEGIES:
octopus
This resolves cases with more than two heads, but refuses to do a
complex merge that needs manual resolution.
For instance:
~ $ 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
Indeed, when fast-forwarding to A, the label of master has not been pushed forward, though the tree has.
~/testdir(master) $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: myfile
#
If, looking at the code of what the octopus merge does, I perform this manually (look above for hashes):
~/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.
In the other direction (merge B A
), now, if you look again at the code of merge-octopus, it tries to detect the branch we are trying to add is already in the tree (second case
of the for
loop). Indeed, at the merge of A, it sees ac5b51c (a.k.a. A's head) is the common ancestor of A and B, and aborts without doing the second read-tree
.
This behavior is consistent with the fresh version of git : though I've pointed to v.1.3.1, this is still happening with my version.
~/testdir(master) $ git --version
git version 1.7.5.4
tl;dr : you want your octopus merge branches to touch distinct files