bug ? - RE: [darcs-users] Re: Merge and conflicts

David Roundy droundy at abridgegame.org
Wed Mar 10 12:43:15 UTC 2004


On Wed, Mar 10, 2004 at 11:19:46AM +1100, BARBOUR Timothy wrote:
> > From: David Roundy [mailto:droundy at abridgegame.org]
> [...]
> It would be nice if the manual explained how to deal with conflicts.

Hmmm.  Good idea.  I've added a TODO on this, since I won't have time for
it today.  It probably deserves a separate section in the introduction or
getting started or somewhere... or maybe I need to add a "using darcs"
chapter to bridge the gap between "getting started" and the specific
command references.

> I just tried essentially the above scenario. It worked as you describe,
> however there is something that puzzles me: if I start pulling the patches
> to a third repo (initially empty), the conflict resolution patch behaves
> differently if it is pulled with the other patches or separately, even
> though the order is the same. More specifically, I have tried two ways to
> pull the patches:
> 
> (i) pull -a <src repo>
> (ii) pull <src repo>  ... ;  pull <src repo> ...
> 
> (i) works as expected, and there is no conflict (presumably because the
> resolution patch resolved it). OTOH, (ii) offers to pull each patch
> individually, with the resolution patch last. If I pull each patch in turn,
> there is no conflict. If I pull all except the resolution patch, there is a
> conflict (understandably). However if I subsequently pull the resolution
> patch, there is still a conflict, and it is a more complex one! I would have
> expected it to resolve the conflict, regardless of whether it was pulled in
> the same pull as the other patches.

This is expected behavior, and is the reason for the --no-resolve-conflicts
option in darcs apply.  That option exists specifically so that this
problem won't happen on pushable repositories.  I could add the
--no-resolve-conflicts option to pull as well, but it's hard to see a
practical context in which one would want to use it.

The problem is that in scenario (ii) when you pull the two conflicting
patches and there is a conflict, darcs tries to resolve the conflict in the
working directory.  As a result, your working directory is no longer
identical to the contents of the repository (i.e. darcs whatsnew shows
changes, even though you didn't make them).  When you pull the conflict
resolution patch, it doesn't conflict with any of the patches in the repo,
but it *does* conflict with the conflict resolution which is already in
your working directory, and that is what causes the trouble.

The problem is that when darcs modifies your working directory to have a
conflict resolution (or conflict marker) it immediately forgets where those
changes came from, and afterwards treats them exactly as if you had made
them yourself.  I think I have a solution to this problem (which I was
previously aware of as a user interface problem, but hadn't even really
thought of looking for a solution to before).

If, when we resolve a conflict, we store the conflict resolution itself as
a patch somewhere (as we currently do upon revert in order to make unrevert
possible).  Then when the next pull is done, the local changes can be
broken into two halves, the automatic conflict resolution followed by any
human-made changes.  If the automatic resolution commutes with the
human-made changes, then it can be undone prior to merging.  Then if it
commutes with the merged patch it can be reapplied.  If it doesn't, then it
means that the merged patch either resolved the conflict or added to the
conflict, and in either case, we don't need the old conflict resolution.
Note that I'm being vague about my commutations.  In practice I'll have to
do it correctly, but it shouldn't be hard to sit down with pen and paper
and work out which direction which patches need to be commuted in each
case.

I'm not quite sure how much of a change this will be internally.  I suspect
it's simple enough that it should be safe to do this soon before darcs 1.0,
and it would definitely be a major improvement.  The primary possible
problem area is that I've assumed for simplicity that there is only one
conflict present, but in practice there could be a large number of
conflicts.  So we'd really have to store and deal with a whole slew of
conflict resolutions, any subset of which may be resolved by any given
patch.  So the problem will certainly be a bit hairy, but *should* be
tractable.  It's definitely worth letting the idea simmer in my head for a
few days before coding anything up.  Ideas are like soup--they improve with
time.  :)

It has occurred to me that the goal should be that pulling patches in any
order (which is allowed by dependencies) should give the same final result,
provided the final repository contains no conflicts.  It would be helpful
to have a test in the test suite to verify this, so if you're sufficiently
motivated (and have enough spare time), it would be helpful to me to have
a script that creates a repository with a bunch of conflicts and conflict
resolutions (the more complicated the better) and then checks that you get
the same final result independent of the order in which you pull the
changes.  Obviously, such a test would fail currently, which would make it
a bit awkward to write, but that's precisely why I'm hoping to avoid doing
this myself.  :)  Another exciting possibility is that if I can make these
changes right, the --no-resolve-conflicts wouldn't be needed for pushable
repositories.  You'd still want it for efficiency reasons, but it means I'd
be able to take it off of my darcs pushable test repo, and get just a tad
more testing of the conflict resolution code.
-- 
David Roundy
http://www.abridgegame.org




More information about the darcs-users mailing list