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

Tree conflict detection in 'svn merge'

From: Stephen Butler <sbutler_at_elego.de>
Date: Thu, 14 Feb 2008 16:09:52 +0100

Hello tree-conflict fans,

The first phase of tree conflict detection is available in the tree-
conflicts feature branch. See this post for a recap of the current
functionality implemented by this branch:

   http://svn.haxx.se/dev/archive-2008-01/0296.shtml

In extending the current tree-conflict-detection scheme to cover
'svn merge', we want to avoid presenting the user a lot of apparent
tree conflicts that involve files with no common ancestry. To weed
out these false positives, we have to query the repository. Our
current plan is described below, arranged according to use case.
The use cases are described in the recap email above and in
notes/tree-conflicts/use-cases.txt.

We would be grateful for any feedback.

Thanks,
Steve

==========
USE CASE 4
==========

A file modified in the merge diff does not exist at the current URL.
If a file at the current URL has been deleted in the parent dir's
history, then we might have a tree conflict.

A tree conflict exists if all of the following predicates are true:

1. The merge operation is compatible with tree conflict detection:
    We check specific fields of the merge-command baton (of type
    merge_cmd_baton_t). If all of the following boolean fields have
    the given values, we might have a tree conflict.

    a. (same_repos == TRUE) Both of the source URLs, merge-left and
        merge-right, must be in the same repository.

    b. (sources_ancestral == TRUE) The merge-left URL given to the
        merge command must be an ancestor of the merge-right URL.

    c. (ignore_ancestry == FALSE) The rest of the predicates below
        depend on ancestry queries, so if the user wants to ignore
        ancestry there's not much point in looking for tree conflicts.

    d. (record_only == FALSE) A record-only merge operation updates
        mergeinfo without touching files.

2. The file at merge-left is an ancestor of the file at merge-right:
    We call svn_client__get_youngest_common_ancestor(). If the YCA
    is the merge-left file, we might have a tree conflict. Note that
    this is a more specific query than #1b above.

3. In the history of the current directory, a file by this name has
    been deleted: In the repository, we will call the function
    svn_repos_deleted_rev(), passing a "start" revision in which the
    file existed and receiving a "deleted" revision in which the file
    was deleted. But first we have to choose a valid "start" revision,
    which is a bit tricky since we don't yet know whether the file
    ever existed in the current directory.

    a. The parent dir and the corresponding dir at merge-left have
       a common ancestor: We pass the two directories to
       svn_client__get_youngest_common_ancestor(). If a common
       ancestor exists, we might have a tree conflict.

    b. The file existed in the parent dir's common-ancestor revision:
       If svn_ra_check_path() says that a file by that name existed
       in the parent dir at the common-ancestor revision, we might
       have a tree conflict.

    c. The file has been deleted in the parent dir between the
       common-ancestor revision and the working copy's base revision:
       We call svn_ra_get_deleted_revnum(), passing it the common-
       ancestor revision as the "start" revision and the base revision
       as the "end" revision. Note that this function does not yet
       exist in the remote-access layers. We'll have to implement it.

4. The file at merge-left and the file deleted in the parent-dir's
    history have a common ancestor: We pass the merge-left file and
    the "last surviving revision" of the file, derived from #3c above,
    to svn_client__get_youngest_common_ancestor(). If they have a
    common ancestor, we have a tree conflict (finally!).

==========
USE CASE 5
==========

An existing file is deleted by the merge diff. We don't want to lose
any text changes that are unique to the file at the current URL.

A tree conflict exists if all of the following predicates are true:

1. The merge operation is compatible with tree conflict detection.
    Same as #1 in use case 4.

2. The current file and the file at merge-left have a common
    ancestor: We can call svn_client__get_youngest_common_ancestor().
    If the ancestor exists, we might have a tree conflict.

3. The text of the current file does not match the text of the
    "last surviving revision" of the file after merge-left: The last
    survivor is found by passing svn_ra_get_deleted_revnum() the
    merge-left revision as "start" and the merge-right revision as
    "end". Thankfully, this is simpler than #3 in use case 4. I
    think we can call svn_client_diff_summarize2() to compare the
    files. If there is a text difference, we have a tree conflict.

==========
USE CASE 6
==========

A file deleted by the merge diff does not exist at the current URL.
If a file at the current URL has been deleted in the parent dir's
history, then we might have a tree conflict.

A tree conflict exists if all of the following predicates are true:

1. The merge operation is compatible with tree conflict detection.
    Same as #1 in use case 4.

2. In the history of the parent directory, a file by this name has
    been deleted. Same as #3 in use case 4.

3. The file at merge-left and the file deleted in the parent-dir's
    history have a common ancestor. Same as #4 in use case 4.

It would be nice to skip the tree conflict if the double-delete is
caused by two rename operations that have the same destination.
But we have to mark this as a tree conflict due to the current lack
of "true rename" support. See notes/tree-conflicts/detection.txt
for more on this topic.

-- 
Stephen Butler | Software Developer
elego Software Solutions GmbH
Gustav-Meyer-Allee 25 | 13355 Berlin | Germany
fon: +49 30 2345 8696 | mobile: +49 163 25 45 015
fax: +49 30 2345 8695 | http://www.elegosoft.com
Geschäftsführer: Olaf Wagner | Sitz der Gesellschaft: Berlin
Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-02-14 16:10:06 CET

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