Using the graft command

709 views
Skip to first unread message

Angel Ezquerra Moreu

unread,
Mar 19, 2012, 4:13:31 AM3/19/12
to mercurial
Hi,

I am testing the graft command and I am having some problems. I
believe that I don't understand how it works.

Grafting a revision that does not have any conflicts works fine. The
problem happens when there is a conflict.

To test this I created two heads that are children of the same base
revision. Both modify the same line on the same file. I updated to one
of them and tried to graft the other one.

I expected to get a conflict and I did. Mercurial opened my default
merge tool (Araxis Merge) but it opened it in 2 panel mode, which
means that I did not get the usual parent1, base, parent2 view.
Instead I got a 2 file view, with one file being the local file and
the other some temporary file.

I did not change anything (and I did not save the unmodified local
file). I just closed the merge tool. I expected that the graft would
be aborted and that I would be able to resolve the conflicts. Instead
the graft operation proceeded. I got a new revision on top of the
graft base. This new revision was empty.

Is that the expected behavior?

Angel
_______________________________________________
Mercurial mailing list
Merc...@selenic.com
http://selenic.com/mailman/listinfo/mercurial

Matt Mackall

unread,
Mar 19, 2012, 11:14:41 AM3/19/12
to Angel Ezquerra Moreu, mercurial
On Mon, 2012-03-19 at 09:13 +0100, Angel Ezquerra Moreu wrote:
> Hi,
>
> I am testing the graft command and I am having some problems. I
> believe that I don't understand how it works.

The code to understand is here:

http://www.selenic.com/hg/file/63a1bed65fa3/mercurial/commands.py#l2612

Most of the magic is in line 2622, where it calls 'update' using a
custom ancestor (the first parent of grafted changeset). So if you have
a graph that looks like:

a-b-c-d-e-f-G
\
x-y-z <- working directory

..when you graft G onto z, it'll pretend the graph actually looks like
this:

f-G
\
z

Semantically, this says "find the one change, f->G, and add it to z."
Or, equivalently, "find all the changes, f->z, and add it to G."

It's that simple. Everything else about the merge mechanics stays the
same.

> I expected to get a conflict and I did. Mercurial opened my default
> merge tool (Araxis Merge) but it opened it in 2 panel mode, which
> means that I did not get the usual parent1, base, parent2 view.

Given that everything else about the merge mechanics stays the same,
that's a very strange result. Mercurial certainly provides an ancestor.

> I did not change anything (and I did not save the unmodified local
> file). I just closed the merge tool. I expected that the graft would
> be aborted and that I would be able to resolve the conflicts. Instead
> the graft operation proceeded. I got a new revision on top of the
> graft base. This new revision was empty.

As always, file merges are presumed to have worked when the merge tool
exits with no error level.

--
Mathematics is the supreme nostalgia of our time.

Angel Ezquerra Moreu

unread,
Mar 20, 2012, 10:46:25 AM3/20/12
to Matt Mackall, mercurial
On Mon, Mar 19, 2012 at 4:14 PM, Matt Mackall <m...@selenic.com> wrote:
> On Mon, 2012-03-19 at 09:13 +0100, Angel Ezquerra Moreu wrote:
>> Hi,
>>
>> I am testing the graft command and I am having some problems. I
>> believe that I don't understand how it works.
>
> The code to understand is here:
>
> http://www.selenic.com/hg/file/63a1bed65fa3/mercurial/commands.py#l2612
>
> Most of the magic is in line 2622, where it calls 'update' using a
> custom ancestor (the first parent of grafted changeset). So if you have
> a graph that looks like:
>
> a-b-c-d-e-f-G
> \
> x-y-z <- working directory
>
> ..when you graft G onto z, it'll pretend the graph actually looks like
> this:
>
> f-G
> \
> z
>
> Semantically, this says "find the one change, f->G, and add it to z."
> Or, equivalently, "find all the changes, f->z, and add it to G."
>
> It's that simple. Everything else about the merge mechanics stays the
> same.

Matt,

thanks for the explanation. That makes it much clear.

>> I expected to get a conflict and I did. Mercurial opened my default
>> merge tool (Araxis Merge) but it opened it in 2 panel mode, which
>> means that I did not get the usual parent1, base, parent2 view.
>
> Given that everything else about the merge mechanics stays the same,
> that's a very strange result. Mercurial certainly provides an ancestor.

You are right. It seems that it is a problem with the merge tool.
I tried to perform a regular merge from the command line and I got the
same problem. That is the merge tool, Araxis Merge, opened in the 2
panel "diff mode" (rather than in the 3 way "merge mode"). Closing the
Araxis Merge window let mercurial believe that the merge had been
successful.

When I switched the merge tool to kdiff3, everything worked as
expected. KDiff 3 was open in the 3 way "merge mode" and closing
without saving led to mercurial saying that the merge was aborted.
Doing a graft rather than a merge worked as well, with the graft being
cancelled when I closed kdiff3 without saving.

>> I did not change anything (and I did not save the unmodified local
>> file). I just closed the merge tool. I expected that the graft would
>> be aborted and that I would be able to resolve the conflicts. Instead
>> the graft operation proceeded. I got a new revision on top of the
>> graft base. This new revision was empty.
>
> As always, file merges are presumed to have worked when the merge tool
> exits with no error level.

It seems that in "diff mode" Araxis Merge always exits with a 0 error
level (which makes sense).

The weird thing is that running the same merge operation from
TortoiseHg Araxis Merge is open correctly in 3 way merge mode. I don't
understand why the behavior of TortoiseHg and plain mercurial is
different.

Angel

Reply all
Reply to author
Forward
0 new messages