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

Re: tree conflicts and directories discussion

From: Julian Foad <julianfoad_at_btopenworld.com>
Date: Thu, 10 Apr 2008 23:32:06 +0100

Dear tree conflict fans,

Can you help me check whether we're going the right way about detecting
conflicting directories? I have a few points in particular to raise.

HOW A TREE CONFLICT IS REPORTED

The reporting is not something we particularly need to discuss in this thread.

HOW A TREE CONFLICT AFFECTS THE WC

When a conflict occurs, the WC should be left in a state that enables the user
to resolve the conflict. What does this mean in practice?

I had been thinking the following would be a clean and desirable design,
bearing in mind that the topic is tree-conflict _detection_ only:

   - "Leave the WC untouched by this attempted incoming change."

However, the way text conflicts work is:

   - "Leave the WC containing (files that have) all of the information about
both sides of the conflict."

The doc <notes/tree-conflicts/scratch-pad.txt> contains a "Scenario Playground"
in which the thoughts appear to be more along the lines of:

   - "Leave the WC as if the incoming change had been applied first and then
the user had made the necessary changes to get back to the state he wanted."

I have not yet tried to define how either of these other styles would apply
consistently to all cases.

Your thoughts, please.

WHICH CASES WE WANT TO DETECT

(This section is long. A practical difficulty is below, marked with "!!!".)

I think the conflicts we want to detect on directory operations are exactly
analagous to those on files, with the difference that to "modify" a directory
means to modify anything in the whole directory tree.

For both files and directories, and for all of "update", "switch" and "merge",
the same principle applies: if the incoming change is trying to
delete/move/modify something that has already gone away from the equivalent
path in the target, or to create something that is already created in the
target, that's a tree conflict.

Formally:

   | Change ... merged onto ... TargetChange
   | | |
   | v | CREATE GO-AWAY REPLACE MODIFY
   | ------- + ------- ------- ------- -------
   | CREATE | C X X X
   | |
   | GO-AWAY | X C C C
   | |
   | REPLACE | X C C C
   | |
   | MODIFY | X C C merge

   Change = incoming change being applied by "update" or "switch" or "merge"
   TargetChange = how the target looks, compared with merge-left source

   C = tree conflict
   X = can't happen, by definition
   merge = the kind of merge that Subversion already does

   CREATE:
   # file-add(F) = add-new(F) or copy(to F)(and modify?)
   # dir-add(D) = add-new(D)(deep?) or copy(to D)(and modify?)

   GO-AWAY:
   # file-del(F) = del(F) or move(F away)
   # dir-del(D) = del(D) or move(D away)

   REPLACE:
   # file-rep(F) = (file-del(F) + file-add(F))
   # dir-rep(D) = (dir-del(D) + dir-add(D))

   MODIFY:
   # file-mod(F) = text-mod(F) and/or prop-mod(F)
   # dir-mod(D) = prop-mod(D) and/or file-mod(child-F) and/or dir-mod(child-D)

Meaning of "target change":

For "update" and "switch", the base for both the incoming change and the target
change is the same thing: the WC "base". The "target change" is the local
change scheduled in the WC.

For "merge", the "target change" against a "base" is in fact easy to define.
There may be a common ancestor of the two branches, but Subversion doesn't care
about that when applying the change. All it cares about is whether the target
looks the same as the merge-left source or whether it looks like it has already
been changed, and that is what we mean here by a "target change". This "target
change" that Subversion sees can be due to what the target branch already looks
like in the repository, and/or due to local scheduled WC changes.

!!!
A practical difficulty arises with determining the "target change" in a "merge"
situation. The correct behaviour is to compare the merge-left source and the
target in order to decide whether the target path under consideration is to be
considered "created" or "gone away" (these being easy to determine) or
"replaced" or "modified" (these being potentially much more expensive to
determine). A directory tree could be modified only somewhere deep in its
hierarchy and there is no way to determine this just by looking at the
information immediately available for the directory itself.

The implementation uses the diff_callbacks mechanism to communicate the change
being applied by the merge. We are adding (in the "diff-callbacks3" branch)
"dir open" and "dir close" callbacks. Perhaps we can use something like this to
provide enough information to more quickly determine whether a given directory
D in the merge-left source is in fact identical to the corresponding one in the
target.

The current approach taken in the implementation is, when a case occurs that
might be a conflict (and the only such case is a merge trying to delete a file
that might have be "modified" (meaning "different") on the target), we do a
full-text comparison if necessary. Now that we want to extend this to the case
of a directory tree, we think a full comparison may be prohibitively expensive.

Thoughts?

MISC.

I have attached some notes on what tree-conflicts work is happening where, and
my opinion of the level of agreement we've reached on the various aspects of
this work.

- Julian

WHAT TREE-CONFLICTS WORK IS GOING ON, AND WHERE IS IT?

Documentation:

  /trunk/notes/tree-conflicts/

  - Docs need a bit of an overhaul. It's not clear what is current and what is
    out of date.

Main coding:

  /branches/tree-conflicts/

  - Currently, this detects the most common cases of conflicting operations on
    files. The user interface is rough. Several classes of conflict condition
    are not yet detected, especially conflicting operations on directories. The
    state of the WC after a conflict, and the ability for the user to resolve
    the conflict, are not well considered.

Other patches needed:

  /branches/diff-callbacks3/

  - Issue #3134 "Extend client diff-callbacks for directory navigation".

  - Fairly simple change to add dir-open and dir-close to the diff-callbacks
    that are used to perform merges, in order to be able to do conflict
    detection stuff.

  /branches/double-delete/

  - Issue #3156 "Delete should conflict with delete (at the repos level)".

  - Fairly simple patch to fix a bug whereby the repos silently merges
    double-deletes in some circumstances where it should be an error. There's
    some issue with this fix affecting a merge test, discussed in the issue.

Open issues:

  Listed in the tracker with "tree-conflicts" as part of the URL field.

  - There are about 10 such issues at the moment.

LEVEL OF CONSENSUS REACHED IN THE SPECIFICATION OF TREE-CONFLICTS BEHAVIOUR

Goals and non-goals:

  - General agreement.

What cases are detected as tree conflicts:

  - General agreement. Includes obvious conflicts and local obstructions and
    generally anything that prevents clean application of a change.

  - Exception: Unclear how sparse WCs should behave.

How Subversion presents tree conflicts:

  - General agreement. The precise form of the messages and status indications
    are not seen as important as long as they give enough information.

  - Exception: Unclear on the expected WC state when a conflict is raised, which
    is an important issue related to resolving. e.g. the outcomes proposed in
    <trunk/notes/tree-conflicts/scratch-pad.txt> are radically different from
    some of our thinking.

How the user resolves tree conflicts:

  - Some thoughts, but not well specified.

How tree conflicts block commits and further merges:

  - General agreement. The blocking of commits is expected to be straightforward.

  - The blocking of further merges may need a little more thought.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-04-11 00:32:28 CEST

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.