git octopus merge 'silently' not merging some branches

489 views Asked by At

I am having some unexpected results that seem to be based on the ordering of branches given to git merge when performing an octopus merge.

The following script will replicate my situation

#!/usr/bin/env bash

rm -rf TEMP

# create area to work in
mkdir TEMP
cd TEMP/
git init

# work on master
echo "hello world" > file
git add file 
git commit -m "initial commit"

# create branch which is at the same point as master
git branch hasnt_moved

# create another branch 1 commit ahead
git checkout -b feature_branch_with_work
echo "some interesting work" > other_file
git add other_file 
git commit -m "work on feature branch"

git checkout master

# always should also have some work ahead of master
git checkout -b always
echo "some work on always" > other_other_file
git add other_other_file 
git commit -m "work on always branch"

# back to master
git checkout master

# now try a merge
#git merge --no-edit --strategy=octopus always hasnt_moved feature_branch_with_work

# however if I had ran this then it would be merged in
#git merge --no-edit --strategy=octopus hasnt_moved always feature_branch_with_work

# I would also expect this to give the same resutls
#git merge --no-edit --strategy=octopus always feature_branch_with_work hasnt_moved

Here is the state of my git tree after running the above script branches before any merge

You can see the 3 commented out lines at the end, below is each line and the graph resulting from running that command on the tree (produced via gitk --all, after running each command you can get 'back' to the start via git reset --hard hasnt_moved)

The following 2 cases are as expected (pay attention to the ordering of the branch arguments)

git merge --no-edit --strategy=octopus hasnt_moved always feature_branch_with_work

expected results form merge

git merge --no-edit --strategy=octopus always feature_branch_with_work hasnt_moved

expected results form merge

This final case produces unexpected results, as the always branch is not included in the final merged master branch (pay attention to the ordering of the branch arguments).

git merge --no-edit --strategy=octopus always hasnt_moved feature_branch_with_work

actual results from merge

If I run the merges one by one I get the expected result:

git merge --no-edit --strategy=octopus always
git merge --no-edit --strategy=octopus hastn_moved
git merge --no-edit --strategy=octopus feature_branch_with_work

manual results given expected results

I am wondering why the ordering of the commits given to octopus merge can sometimes cause the always branch to not be merged into master.

1

There are 1 answers

1
John Szakmeister On

Looks like you're stumbling onto a legacy syntax. It turns out that git merge used to have the form:

git merge <msg> HEAD <commit>...

It's still supported for legacy reasons. Your merge command:

git merge --no-edit always hasnt_moved feature_branch_with_work

is accidentally stumbling on it. In this case always is seen as the message, and hasnt_moved is at the same revision as HEAD. As a result, git is treating this command as:

git merge --no-edit -m "always" feature_branch_with_work

I'm not sure of the former syntax of git, but it seems to me that if it expected to see the actual word HEAD that git should be a little more strict before dropping to this syntax. However, I doubt that was the case.

You can work around it by explicitly providing a message with the -m parameter:

git merge --no-edit -m "Merge always, hasnt_moved, and feature_branch_with_work"
    \ always hasnt_moved feature_branch_with_work

Then the octopus merge happens as expected.

BTW, you can see the old syntax of git merge on the git-merge man page.