[RFC] A better way to help users understand and resolve confclits
Guilhem Bichot
guilhem at sun.com
Tue Aug 25 11:08:16 BST 2009
Hello Vincent,
Vincent Ladeuil a écrit, Le 13.08.2009 16:03:
>>>>>> "Guilhem" == Guilhem Bichot <guilhem at sun.com> writes:
>
> <snip/>
>
> Guilhem> I think what can enlighten users most is explanations like you wrote:
>
> Guilhem> bzr resolve --interactive <item>
>
> Guilhem> <base> is <revid>/<revno>
> Guilhem> <other> wants to create <item> bzr created <item>.moved
> Guilhem> <this> keeps <item>
> Guilhem> 1) Right, get rid of .moved
> Guilhem> 2) Wrong, .moved is the good one, get rid of <item>
> Guilhem> 3) Abort, let me handle that myself.
> Guilhem> 4) Do nothing, just mark as resolve
When I started doing MySQL code merges using bzr, which are often large
(tens of conflicted files), I quickly hit the problem that for most text
conflicts, I couldn't take a good decision without looking at revision
history of the TREE and MERGE-SOURCE branches. Here's an example:
<<<TREE
2
===BASE
1
===
>>>MERGE-SOURCE
That is, TREE changed a line whereas MERGE-SOURCE deleted it.
Then what should I do:
- if MERGE-SOURCE just deleted "1", I may consider deleting "2"
- but if MERGE-SOURCE deleted "1" and inserted it in some other file
(that is, it was actually a code move), I should rather delete "2" and
put it into some other file.
So I need to see the diff associated with the revision which deleted "1"
(to see if "1" was put in some other file). Either through "bzr
gannotate" or "bzr qlog FILE", usually.
This is even more pressing when using --weave where there is no BASE
section.
Fortunately there is a GUI plugin which I now use for every merge:
https://launchpad.net/tetard
As useful goodies, it also allows doing graphical diffs between the TREE
and merged file (so that, after doing lots of editing to fix several
conflicts in one file, you can see what you have done).
Given that "bzr resolve --interactive" and this plugin have similar
goals (except that one is a GUI), and I know the plugin has made my
merge experience easier, I suggest looking at features of the plugin as
one source of inspiration.
Here's the help text for the GUI plugin:
***********
Purpose: A graphical user interface to help conflict resolution in merges
Usage: bzr mergeboard
Options:
-v, --verbose Display more information.
-q, --quiet Only display errors and warnings.
-e ARG, --editor=ARG editor program (default: from EDITOR environment
variable)
--usage Show usage message and options.
-d ARG, --diff=ARG diff program (default: kdiff3)
-h, --help Show help message.
Description:
Assuming you are merging branch B into branch A: to use this command,
you need three checked-out branches on disk:
- "local branch": A
- "remote branch": B
- "merge branch": a branch identical to A, where you have started the
merge:
bzr branch A A_merge; cd A_merge; bzr merge B; bzr mergeboard
Fill in the "local" and "remote" text entries, pick a conflicted file
in the drop-down list, then use buttons.
This command is limited to text conflicts.
The "revtool" buttons assumes that you have a plugin providing a
"bzr revtool FILENAME" command.
The "extmerge" button assumes that you have the "extmerge" plugin.
The "gannotate" buttons assumes that you have the "bzr-gtk" plugin.
To create a shortcut for this command, see "bzr help alias"
**********
At least, if it's impossible to display revision history via 'bzr
resolve --interactive', a greatly flexible workaround could be to allow
the user to define, via some configuration variables, additional actions
for this command; it could look like this in the '.conf' file:
resolve_interactive=("Text", "annotate TREE version", "bzr gannotate
%t"),("Text", "display history of MERGE-SOURCE version", "bzr qlog %m")
where:
- "Text" means that the action should be added only when the conflict is
of type "Text"
- the second element of the sequence is the human-readable description
of the action
- the third element is a system command which would be executed; %t
stands for "a path to the TREE version of the file" and %m for "a path
to the MERGE-SOURCE version of the file" (possibly magically put in a
temporary file before executing the action).
And then 'bzr resolve --interactive' would look like:
1) built-in action (do this)
2) built-in other action (do that)
3) abort, let me handle it
4) just mark it resolved
5) annotate TREE version
6) display history of MERGE-SOURCE version
Note that the tetard plugin executes "gannotate" in a non-blocking mode
(GUI returns control before the "bzr gannotate" window is closed), so
that you can have several annotate or history windows open at the same
time, which helps in certain cases (history of TREE and history of
MERGE-SOURCE for example).
--
Mr. Guilhem Bichot <guilhem at sun.com>
Sun Microsystems / MySQL, Lead Software Engineer
Bordeaux, France
www.sun.com / www.mysql.com
More information about the bazaar
mailing list