Google Summer of Code '19: Add functionality to store an unresolved merge-state

Martin von Zweigbergk martinvonz at google.com
Wed May 15 12:50:41 EDT 2019


*From: *Navaneeth Suresh <navaneeths1998 at gmail.com>
*Date: *Wed, May 15, 2019 at 5:13 AM
*To: *Pierre-Yves David
*Cc: *mercurial-devel

On Tue, May 14, 2019 at 5:51 PM Pierre-Yves David <
> pierre-yves.david at ens-lyon.org> wrote:
>
>>
>>
>> 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[1]
>> > <
>> 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
>> > merge-state.
>>
>> 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 ?
>>
>
> Yes. For example, if a user wants to fix an urgent bug without losing
> their partly done enormous conflict resolution, this project will help them
> to store the conflicts and resume the resolution after fixing the bug. In
> the current scenario, they are only allowed to either fully discard or
> complete the partly done resolution to perform a new commit.
>
>
>>
>> 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
>> independently).
>>
>
> From the UI point of view, it appeared to me as shelving with conflicts.
>

Good idea.


> I thought of introducing two commands `hg store-conflicts` and `hg
> restore-conflicts`.
>

Or even reuse `hg shelve` and `hg unshelve`?

For the user, it should be pretty easy to get things done. But, as you
> told, it should require much work and the internal workflow might be
> complex. (in the later part of the mail)
>
>
>>
>> > 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)
>>
>
> We might require a special commit as this changeset shows properties which
> are different from normal commits (not publishable nature, etc.) But, we
> can make use of tools you suggested such as extra mapping.
>
>
>>
>> > 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
>> file content
>>
>
> I had a look at the old Imerge extension's format which was used to split
> a merge into pieces and it looked good to me. In my proposed method, it
> shouldn't allow another merge after `hg store-conflicts` until the user
> triggers `hg restore-conflicts`. So, the merge-state living at .hg/merge
> can be used for `hg restore-conflicts`. (Note that my official proposal
> doesn't include bookmarks and it deals with hidden commits for conflicts)
>
>
>>
>> > 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
>>    R foo
>>    U bar
>>
>> My idea would be add a flag to make it possible to commit anyway.
>> Something like:
>>
>>    $ hg commit --unresolved
>>
>
> Interesting.
>
>
>>
>> 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
>>
>
> IIRC, @pulkit told me that the new changeset by the user after committing
> the unresolved files shouldn't come as a child of the "unresolved" commit.
> This is to stop getting the "unresolved" commits published.
>
>
>>
>> However it can get resolved.
>>
>>    $ hg up YOURMERGE
>>    $ hg resolve -l
>>    R foo
>>    U bar
>>    $ hg resolve bar
>>    $ hg resolve -l
>>    R foo
>>    R bar
>>
>> And the merge can be concluded (not sure of the UI)
>>
>>    $ hg merge --continue
>>
>> or maybe.
>>
>>    $ hg amend
>>
>
> `hg amend` sounds sweet to me. But, as of now, a user is not allowed to
> amend changeset with children. (Note that the DAG has other changesets
> after "conflict" commit. I think you assumed the user has commits directly
> on top of the "conflict" commit)
>
>
>>
>> > 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.
>>
>
> IIUC, shelving an unresolved merge and unshelving that later constitutes
> the main part of the project. I stopped thinking about that approach
> because this also involves sharing the "conflict" changesets with other
> users so that they can help with the resolution (I thought of adding
> something like --with-conflicts to push and pull commands.)
>
>
>>
>> The main technical questions are:
>>
>> A) How do we flag a changesets as "unresolved"
>>
>
> The extra mapping {'internal' : 'unresolved'} looks good to me.
>
>
>> b) Where do we store the usual merge-state information ?
>>
>
> I thought of reusing the merge-state information stored at .hg/merge. To
> be curious, is allowing a merge after storing a file with conflict
> required? Otherwise, we can use the same information.
>
>
>> c) Where we store the multiple alternative content for the unresolved
>> file (local version, current version, [remote version])
>>
>
> .hg/merge (if we are not cleaning the merge-state and thereby not allowing
> a merge before restoring the "conflict" commit)
>
>
>>
>> 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
>>
>
> This project also involves "conflict" changeset publishing feature when
> explicitly called by the user. (I have already talked about this)
>
>
>> * propagating unresolution (what happen when you rebase a change to a
>> file unresolved
>
>
>> And of course the general question of the user experience and comand
>> workflow
>>
>> 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.
>>
>
> I quite liked the plan. I always wanted to split things into pieces and
> work on one by one. This isn't possible per se in my proposed method(which
> is still incomplete). However, some things aren't clear enough at this
> point. I would like to go with your method. I hope now you have a better
> idea of the project. From now on, I would like to focus on your proposed
> method starting from `hg merge`. Thank you for this. What should be a
> kickstart in your opinion?
>
>
>>
>> Cheers,
>>
>> --
>> Pierre-Yves David
>>
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.mercurial-scm.org/pipermail/mercurial-devel/attachments/20190515/c0b5b5e9/attachment.html>


More information about the Mercurial-devel mailing list