Merge state v2 forward compatibility issues, and a proposal for v3

Siddharth Agarwal sid at less-broken.com
Tue Nov 17 03:40:49 UTC 2015


So Martin and I discovered a pretty big issue with the way merge state 
v2's forward compatibility works.

For reference, the merge state is on-disk storage of the state of the 
repository in the middle of a merge. It stores things like what commits 
are being merged, what files have been resolved, and what files haven't.

The v2 merge state is supposed to be extensible: new mandatory and 
advisory record types can be added to the merge state, and old versions 
of Mercurial will supposedly either abort or ignore these new record 
types. All that works fine. The problem is that a command that should 
clear out the merge state, like

hg update --clean

or

hg rebase --abort

will abort as well. This means that for a merge containing a mandatory 
record type that a particular version X of Mercurial doesn't support, 
version X of Mercurial will never be able to either progress or abort 
from that point.

This hasn't been a problem so far since we haven't yet added any new 
record types to the merge state, but I've been working on moving 
change/delete conflicts into the merge state. Storage for these 
conflicts will require a new mandatory record type.

So the proposal that Pierre-Yves and I discussed is:

(1) Add a new merge state version 3. The storage format for version 3 
looks very similar to version 2.
(2) Get the forward compatibility story for version 3 right.
(3) For each new record type 'R' with record ['R', 'a', 'b', 'c', ...], 
store:
   - in version 3, 'R' as usual.
   - in version 2, an advisory record type (say 't'), as ['t', 'R', 'a', 
'b', 'c', ...]
   - (version 1 has no change)
(4) For backwards compatibility (to check that a Mercurial with version 
2 but not 3 support hasn't overwritten the merge state), check that 
version 2 and version 3 have the same records. Since versions 2 and 3 
are isomorphic, writing this check is straightforward.

As a bonus -- since we're doing a new format anyway -- we could also add:

(5) A new advisory record type 'a' that indicates what each new 
mandatory record type 'R' does, and maybe what versions of Mercurial 
support it. So e.g. for the new change/delete conflict type 'C', ['a', 
'C', 'change/delete conflicts (supported in Mercurial 3.7+)']

Questions:

(a) Is this reasonable overall?
(b) Is (5) something that's worth doing?
(c) If so, what sort of i18n concerns would there be around (5)?


More information about the Mercurial-devel mailing list