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