[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Monotone-devel] merge conflict resolution process

From: Stephen Leake
Subject: [Monotone-devel] merge conflict resolution process
Date: Tue, 15 Apr 2008 11:31:52 -0400
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/22.1 (windows-nt)

I'd like to propose a process for resolving conflicts (both content
and non-content) during merges.

One problem with the current process is that the revision committed
never existed on disk, and was not tested. So we see lots of "fixed
errors due to merge" entries in logs.

Another problem with the current process is that it requires resolving
all conflicts at once. For a merge with many conflicts, that can be
confusing, and time consuming. If the merge is aborted at any point,
the conflict resolutions that were done must be repeated.

To address both of these points, I propose a process that
incrementally builds a revision in a workspace that is the correct
result of the merge. Then when the user is satisfied that all
conflicts are correctly resolved, an appropriate "merge" command is
issued, using the contents of the workspace as needed.

In detail:

1) Start with a workspace that has one of the merge ancestors as the
   base revision.

2) Run 'automate show_conflicts', save the output in _MTN/conflicts

3) User works thru _MTN/conflicts one conflict at a time, resolving
   each, adding information about how the conflicts are resolved (more

4) User runs tests etc on workspace.

5) When all conflicts are resolved, run 'mtn merge
   --resolve_conflicts'. This reads _MTN/conflict to determine how to
   resolve each conflict.

As an example, consider the 'duplicate-names' non-content conflict,
where a new file with the same name is added in both ancestors.
automate show_conflicts outputs something like this:

     conflict "duplicate name"
    left_type "added file"
    left_name "bar"
 left_file_id [ba4637112ee3e55a6106d647d6c4e04a6643f8eb]
   right_type "added file"
   right_name "bar"
right_file_id [fe6d523f607e2f2fc0f0defad3bda0351a95a337]

To resolve this, the user decides whether the file contents should be
merged, or the files should have different names. If merged, she
manually merges the content, leaving the result in the workspace file
named 'bar'. She then adds the following to this stanza in _MTN/conflict:


If different names, she renames the files (using filesystem, not
monotone commands) in the workspace, and adds these lines to this

 resolved_rename_left "new name 1"
resolved_rename_right "new name 2"

Of course, a GUI tool or new mtn command(s) could asist in reviewing
the conflicts, modifying the workspace, and adding lines to
_MTN/conflict instead of the user directly editing.

Then when 'mtn merge --resolve_conflicts' is run, it reads
_MTN/conflict and checks the constraint that the base revision of the
workspace must be one of the merge ancestors. Then it goes thru each
conflict. For this example, if the resolution is
'resolved_content_ws', one of the conflicting nodes is dropped, and
the other node gets new file content from the corresponding workspace
file. If the resolution is 'resolved_renamed', the two renames are

If by mistake some conflict does not have a resolution listed, the
merge is aborted, leaving the workspace and _MTN/conflicts unchanged.
This preserves all the conflict resolution work the user did to that

Similar resolutions can be specified for most of the other conflicts.
For some of the 'missing root' conflicts, I don't see how to resolve
them short of disapproving one of the ancestor revisions.

If people agree this is a good approach, I'd like to use the
n.v.m.automate_show_conflicts branch to work on implementing it. This
will mostly involve adding the new conflict resolution code to the
merge command.

A similar process could be used for 'update'; that involves more code.
It doesn't seem worthwhile, since you can always 'commit', and then
use this proposed merge process.

-- Stephe

reply via email to

[Prev in Thread] Current Thread [Next in Thread]