[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Merge conflict resolution

From: Stefan Küng <tortoisesvn_at_gmail.com>
Date: 2006-11-22 09:37:29 CET

Daniel Rall wrote:

> While conflict markers might not currently seem like much of a problem
> to most people (at least, to those not grumbling that Subversion is
> "corrupting their files"), Merge Tracking really complicates things.
> In today's Subversion, we apply only one revision range during any
> merge operation. With Merge Tracking, we may apply multiple revision
> ranges during a single merge operation, a rather fundamental
> difference with many ramifications. Once a file has a merge conflict,
> we have to stop applying revision ranges, meaning that we might apply
> only a portion of the revisions requested for merge by the user.

What happens if such a conflict would not exist anymore if all revision
ranges got applied? I'm thinking of a situation where the same line got
changed multiple times over multiple ranges, and the last change would
render the file so that no conflict would occur.
Does it create a conflict which has to be resolved or will that be
handled 'gracefully'?

> Requirements:
> - Allow merge conflicts to be resolved during application of a merge.
> - Allow as much automatic merging to be performed as possible without
> requiring human interaction.
> - Allow declarative conflict resolution to avoid any human interaction
> (e.g. --resolve-conflict-using=[older|theirs|mine]), supporting some
> degree of conflict resolution from merges (e.g. build automation).
> - Maintain compatibility with the diff3 command.
> - Allow for resolution more types of conflicts (e.g properties,
> obstructions, etc.).

Will it be possible to have it work like before? Without user
interaction *during* the merge but get conflicted files which must be
resolved later?
I'm thinking of situations with flaky network connections, where a user
might want to do the merging in one step without interruption, and then
do the resolving later.
In which state of the merge is the callback called? Just to avoid
timeout errors when the user takes too long to resolve such a conflict
during the merge operation.

> Possible implementation:
> Subversion will first attempt a merge via its built-in diff library,
> or the diff3 command specified in its config file (or via the
> --diff3-cmd option, for the command-line client). If a merge conflict
> occurs to either content (file or directory) or properties, it will
> invoke a merge conflict resolution callback provided via its
> svn_client_ctx_t structure (we may provide a default implementation of
> this which calls out to an external binary a la the diff3 command used
> in the original merge). This callback would prompt the user to
> resolve the conflict (when in non-interactive mode), and upon

> resolution allow subsequent merge of revision ranges to occur into the
> same file (important for Subversion's Merge Tracking support). For
> the command-line client, the callback would throw up a prompt
> something like:
> Merge conflict detected for "foo.c" at line 37
> mine:
> struct iovec vec;
> theirs:
> int k;
> older:
> int i;
> Retain (m)ine, (t)hiers, or (o)lder version? _

I suggest to include the line numbers there. Otherwise it may be hard
for the user to find out where exactly in the files that context is.

> Question for IDE developers:
> I'm really curious how IDEs handle this situation today. Taking
> TortoiseSVN as an example, I've heard that its TortoiseMerge diff3
> program is great for conflict resolution (though currently lacking an
> edit mode), but not so great for performing merges of a large number
> of changes (e.g. merging changes from trunk into a feature branch),
> especially when the majority of those changes can be applied
> automaticaly with no merge conflicts (and thus don't need typically
> need a merge GUI). Is this an issue for TortoiseSVN/TortoiseMerge
> today, or am I out of date? How about for other IDE developers? How
> do you guys handle this today? ;-)

If the callback provides the information so that the UI merge tools can
use whole files, this will work ok. If however the callback only
provides the context of the file where the conflict occurs, we'd have to
write a custom merge tool just for this purpose - which is maybe not
such a bad idea anyway.

[copied from other mail]
> I'm assuming that the callback will take care of doing the actual
> merge, and that Subversion libraries will handle the WC meta data
> manipulation. Here's the API I've integrated in the tree delta editor
> (from libsvn_client/repos_diff.c); I may actually want to push this
> deeper, down into the WC's editor:

Is the Subversion internal diff3 called first and this callback only
called if there is a conflict?

> /** A callback used for resolving merge conflicts to content or
> * properties encountered during the application of a tree delta to a
> * working copy.
> *
> * This callback is only invoked when not in "dry run" mode. It
> * provides for a smooth balance of automated merging via a
> * non-interactive diff3 mechanism like Subversion's internal
> * implementation (or an external tool like GNU diff specified via @c
> * SVN_CONFIG_OPTION_DIFF3_CMD), and declarative or interactive merge
> * conflict resolution (e.g via an external tool like TortoiseMerge or
> * Araxis Merge).
> *
> * If @a content_state and/or @a prop_state are not @c NULL, and the
> * conflict is resolved during the callback, set @a content_state
> * and/or @a prop_state appropriately (e.g. likely to @c
> * svn_wc_notify_state_merged); housekeeping for the resolution of @a
> * path will occur automatically. If @a content_state and/or @a
> * prop_state are not @c NULL but returned unchanged, it's assumed
> * that the conflict has not been resolved.
> *
> * All allocations should be performed in @a pool.
> *
> * @a baton is a closure object; it should be provided by the
> implementation,
> * and passed by the caller.
> *
> * @since New in 1.5.
> */
> typedef svn_error_t *(*svn_client_conflict_resolver_func_t)
> (const char *path,
> svn_wc_notify_state_t *content_state,
> svn_wc_notify_state_t *prop_state,
> svn_boolean_t dry_run,
> void *baton,
> apr_pool_t *pool);

I see that this callback only has one 'path' parameter. I don't see
where the information would be to actually do a merge? Doesn't a merge
require at least three files/paths to actually get a conflict which must
be resolved?

Some other thoughts:
* sometimes it's not possible to resolve a conflict without modifying
also other files (not just the one which has the conflict). Will it be
possible for the UI merge tool to just tell "sorry, can't resolve this"
and Subversion will then behave as before and leave the file conflicted?
* it would be nice if the svn:mime-type property value also is passed to
the callback: UI tools could use this information to find out what the
best way would be to resolve a conflict or just to simply adjust the UI
according to the mime type
* if the callback does not provide only the context where the conflict
occurs but whole files, an information is required where Subversion can
not resolve the conflict itself: UI merge tools may use a different
diff3 algorithm which won't see a conflict where Subversion sees one.
Maybe the line numbers of where the conflict is supposed to be.


   oo  // \\      "De Chelonian Mobile"
  (_,\/ \_/ \     TortoiseSVN
    \ \_/_\_/>    The coolest Interface to (Sub)Version Control
    /_/   \_\     http://tortoisesvn.net
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed Nov 22 09:37:55 2006

This is an archived mail posted to the Subversion Dev mailing list.