Google Summer of Code '19: Add functionality to store an unresolved merge-state
pierre-yves.david at ens-lyon.org
Tue May 14 08:21:17 EDT 2019
On 5/12/19 8:31 PM, Navaneeth Suresh wrote:
> Hello everyone,
> I am Navaneeth Suresh, one of the GSoC '19 students with Mercurial. I
> wanted to discuss my project on adding functionality to store an
> unresolved merge-state
> <https://www.mercurial-scm.org/wiki/SummerOfCode/Ideas2019#Add_functionality_to_store_an_unresolved_merge-state> with
> the community. Having gone through past mailing list archives on similar
> issues, I got some ideas on the implementation of the project. However,
> there can be other alternatives and I might encounter some issues which
> I might not aware of. So, I'm sharing my idea of implementation.
> As said by @marmoute, we are storing only one active unresolved
Yes, the active merge state exists in .hg/merge/. It is used for the
operation the triggered a merge (hg merge, hg rebase, etc) and will
exist until the merge is concluded or aborted.
As far as I understand your project, is to offer a third alternative:
delaying the merge resolution until later. Right ?
How do you see the final user experience? What is the workflow to delay
and later conclude/abort a merge? (note: there are some UX details from
you later in this email, but it probably worth being explained
> I am thinking to store it as a visible commit under a
> bookmark having the prefix `conflict/`.
That seems strange. We usually don't do this "data behind a bookmark
namespace" in Mercurial. We have a "internal" phase dedicated to commit
that are internal by product. That would be more appropriate.
However, I am not sure we actually need a special commit. We could store
conflict directly into the commit they intend to be part once resolved.
That would simplify the storage and the UX. (more on that later)
> This should contain metadata
> about the files which are marked as resolved/unresolved by the user. I
> have coded this and made this work by respecting both parents without
> changing the default behavior of `localrepo.commit()` (adding metadata
> about conflicts part is left.)
What format do you intend to use. What do you plan to do to preserve the
> This conflicted state can be later
> restored by rebasing the tip on the top of the commit just before the
> conflict commit and stripping the conflict commit from the DAG. The
> restoring functionality is much hypothetical at the moment and there are
> things to investigate on that.
Okay, the workflow is a bit clearer to me now. However it seems quite
complicated. I would propose a slightly different approach. Let me start
with a simple example:
You are trying to do a merge but there are conflict.
$ hg merge
3 files updated, 2 files merged, 0 files removed, 2 files unresolved
Some of the file can be resolved, but one of the conflict remains
difficult and you need to delay its resolution
$ hg resolve -l
My idea would be add a flag to make it possible to commit anyway.
$ hg commit --unresolved
At that point we have a "regular" merge commit but with some
"unresolved" flag. And the related data can also be stored there.
At that point, this "unresolved" commit cannot move to the public phase.
$ hg phase --public
However it can get resolved.
$ hg up YOURMERGE
$ hg resolve -l
$ hg resolve bar
$ hg resolve -l
And the merge can be concluded (not sure of the UI)
$ hg merge --continue
$ hg amend
> If anyone of you has other thoughts on the implementation, I would love
> to hear that. Also, pros, cons, feasibility, etc. on this proposed way
> of implementation are also welcome.
We need a plan that works well for:
* hg merge
* hg rebase & co (similar to merge, but a bit different)
* hg update
* hg shelve
The approach of "just do a regular commit" works well for `hg merge` and
`hg rebase`. It is a bit less clear with `hg shelve` and `hg update` and
need more thinking.
The idea also comes with interesting properties, for example, you can
shelve an unresolved merge.
The main technical questions are:
A) How do we flag a changesets as "unresolved"
b) Where do we store the usual merge-state information ?
c) Where we store the multiple alternative content for the unresolved
file (local version, current version, [remote version])
I believe all of the above can be solved with a combination of existing
tools. changesets, extra, manifest flag, revlog metadata.
I can also see a couple of other technical questions.
* preventing unresolved changeset publishing
* propagating unresolution (what happen when you rebase a change to a
And of course the general question of the user experience and comand
If you like the plan, we can discuss it more. Can help you to clarify
the remaining questions and design the technical bits. I suggest we
focus on `hg merge` for now. This is the simplest case.
More information about the Mercurial-devel