Subject: Re: [IRC/patches] Failed octopus merge does not clean up

From: Jakub Narebski <[email-masked]>
Date: Wed, 17 Sep 2008 00:53:13 +0200

Dnia wtorek 16. września 2008 02:20, Junio C Hamano napisał:
> Junio C Hamano <[email-masked]> writes:
>> Thomas Rast <[email-masked]> writes:
>>
>>> The merge says
>>>
>>>   Trying simple merge with 5b3e4bb1c2d88d6967fb575729fbfc86df5eaec9
>>>   Simple merge did not work, trying automatic merge.
>>>   Auto-merging foo
>>>   ERROR: Merge conflict in foo
>>>   fatal: merge program failed
>>>   Automated merge did not work.
>>>   Should not be doing an Octopus.
>>>   Merge with strategy octopus failed.
>> ...
>> Read the second from the last line of what you were told by git.  Run "git
>> reset --hard" after that, perhaps.

The problem, as far as I understand it, is not that octopus merge fails.
The problem is that it fails halfway, and it leaves working are in
inconsistent state: git-status output with its "unmerged" suggests that
we are in the middle of the merge, but we are not.

> By the way, there are three failure modes in Octopus.
> 
>  (0) your index (not work tree) is dirty; this is not limited to octopus
>      merge but any merge will be refused;

IIRC the idea of stashing away changes, doing merge, and then unstashing
was shot down as encouraging bad workflows, and more often than not
leading only to mess in workdir and index.

>  (1) while it merges other heads one-by-one, it gets conflicts on an
>      earlier one, before it even attempts to merge all of them.  Recording
>      the heads that it so far attempted to merge in MERGE_HEAD is wrong
>      (the result won't be an Octopus the end user wanted to carete), and
>      recording all the heads the user gave in MERGE_HEAD is even more
>      wrong (it hasn't even looked at the later heads yet, so there is no
>      way for the index or work tree to contain anything from them).
> 
>      The above is hitting this case.

IMVHO the correct solution would be to rollback changes to the state
before attempting a merge. I'd rather 'octopus' did its thing as
transaction; contrary to ordinary merges if merge fails it doesn't
mean necessary that it is in the state of resolvable conflict, state
we can stop at. Perhaps (if it is still a shell script, doing git-stash
at beginning, and either dropping or popping the stash at the end;
or just saving old index if it is built-in).

BTW. does it mean that "git merge a b" might be not the same as
"git merge b a"?

>  (2) it gets conflicts while merging the _last_ head.  It records
>      MERGE_HEAD and allows you to record the resolved result.
> 
> I think originally we treated (1) and (2) the same way, because an Octopus
> is to record the most trivial merge with more than 2 legs, and a rough
> definition of "the most trivial" is "tracks of totally independent works;
> you could merge them one by one and _in any order_, and the result won't
> matter because they are logically independent.  However if they are _so_
> independent, why not record them as merged in one step (i.e. octopus),
> instead of insisting on recording in what order you merged them".
> 
> Obviously, if you get a conflict during Octopus creation, they were not
> tracks of totally independent works, and that is where the "Should not" in
> the message comes from.
> 
> We later relaxed it to allow a conflict at the last step, not because
> recording an Octopus with nontrivial merge is particuarly a good idea we
> should encourage, but because there simply weren't reason not to.

Well, octopus merge could simply fail when merge is nontrivial (not
limited to being tree-level merge only).

-- 
Jakub Narebski
Poland