The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
                               -*- text -*-

This file is a scratch pad for working out current and expected
behaviors for various tree-conflict situations.  It may be considered
unfinished at best -- scatterbrained is more like it.

NOTE:  As Subversion does not actually have real 'move' functionality,
please try to express move-ish use-cases in terms of deletes and
adds-with-history (copies).


===================
BACKGROUND THOUGHTS
===================

This whole thing is, I think, basically about ensuring that the
history of a file isn't allowed to fork and then suffer the
unceremonious death of one of the two resulting lines of history when
the streams are rejoined.

When doing an update, we don't have to worry that the working copy
base file has deviated from the line of history that's being deleted
-- other processes prevent this from happening (you can't commit
to a deleted file; you can't delete a file that's been modified since
you last updated).  But you do have to worry about local mods, which
are a "different path" in the file's line of history than the path
that led to its deletion.

When doing a merge, though, stuff gets really complicated.  Now you
have an arbitrary line of history as the source which you are trying to
"lay down" overtop the line of history of the stuff in your
repository, and the goal remains the same: don't assume that
deviations in those lines should be resolved by disregarding one side
of the fork or the other -- that's ungood.  In the best case you are
trying to append segments of one fork in the history road to the
other, and hopefully you don't leave gaps or cause deviations.  In the
worst case, though, you're dealing with a "line of history" that's
made up on-the-fly (due to your left- and right-side merge sources
being unrelated, or only related as second cousins twice removed, or
something).  This is where the "merge = diff + patch" paradigm really
starts to show its weaknesses (and maybe, just maybe, should have been
a use-case that Subversion disallowed ... if only it weren't so darned
useful for vendor branches...).

Anyway, there appear to me to be some pretty clear goals:

   * Conflicting operations should be marked as such and require user
     interaction to resolve

   * In such a conflicting situation, users would like to be able to
     easily do the following:

        - determine what local mods they've made
        - apply those mods elsewhere if necessary
        - determine what mods conflict with the ones with they
        - overrule the conflict and make their changes anyway

   * Tree conflicts appear to be something special, and should be 
     annotated as such.

So a tree conflict is really just a conflict on the content of a
directory, much like a regular conflict is on the content of a file,
and a prop conflict is on the properties of a file or directory.  To
annotate a tree conflict, we recycle the 'conflict-new' conflict file
slot pointing to a dropped file named dir_contents.trej.  It's
contents can note the details of the tree conflict.  [### TODO: Do we
need to be able to mark files as tree-conflicted, too?]


===================
SCENARIO PLAYGROUND
===================

'svn update' pulls file deletion atop file with local text mods

  NOW:  File is silently unversioned.

  NEW:  File is marked as added-with-history (as of the revision
        previously in the working copy), and placed into a state of
        conflict.  There are no conflict markers, but the .trej file
        notes that our file was deleted in the repository.  User can
        see mods with 'svn diff'; revert still works; resolved+commit
        undoes the deletion and commits the users's mods.

'svn update' pulls text mods onto schedule-delete file

  NOW:  Text mods are silently merged into file's text-base and file
        remains scheduled for deletion.

  NEW:  File remains scheduled for deletion, text-base is up-to-date,
        but file is marked as conflict, and .trej file notes that
        the file was modified in the repository.  

        QUESTION: Should .trej file contain the diff of those mods
        from the repository?

'svn update' pulls dir deletion atop dir containing deep text mods

  NOW:  Directory is removed save for modified files (left
        unversioned).

  NEW:  Modified files are marked as added-with-history (as of their
        working copy revisions), placed into a state of conflict, with
        .trej files noting the deletion of the parent directory.
        Intermediate directories are marked as added (no history) and
        in conflict, with their .trej files noting the deletion of the
        directory.

'svn update' pulls file replacement atop modified file

  NOW:  Behaves as a two-step action: delete over modified file (see
        above), then file add over existing file (which is obstructed
        unless --force is provided.

  NEW:  If the 'delete' step goes as recommended above, we'll wind up
        in a state of conflict already with a schedule-added file.
        Once the 'add' step hits, the operation will be obstructed
        even if --force is provided.

        QUESTION:  Is this desirable?  What's the final state of the
        file after the failed update?  How do the recovery options
        play out from here?  For example, we wouldn't want the file
        scheduled for add-with-history because that commit can't
        succeed (another file already exists in the repository at
        that location).

'svn update' pulls dir replacement atop deep-modified directory

'svn update' pulls file-to-dir replacement atop modified file

  NOW:  Behaves as a two-step action: delete over modified file (see
        above), then directory add over existing file (which is 
        disallowed, even if --force is supplied).

  NEW:
 
'svn update' pulls dir-to-file replacement atop deep-modified directory

  NOW:  Behaves as a two-step action: delete over deep-modified
        directory (see above), then file add over existing directory 
        left over from delete step (which fails).

  NEW:  

'svn merge' pulls file deletion

  NOW:  If there's nothing at the target location to delete, the
        target is "skipped" (?); otherwise the target is removed from
        version control and, if not locally modified, deleted.

  NEW:  All file deletions that would affect a local file and that come
        via merge get sanity-checked, with the client pulling the
        left-side source version of the file down and comparing its
        contents with the to-be-deleted working file.  If they are
        equivalent and there are no local mods to the file, it is
        removed from version control.  Otherwise, we have two sets of
        data we'd like to keep easy track of:  diffs between
        deleted-source and wc base file, and diffs between wc base and
        wc working files.  
        NOTE:  Need more thinkin' 'round these parts...

'svn merge' pulls file modification atop schedule-delete file

  NOW:  "Skipped missing target" message.

  NEW:  File remains scheduled for deletion, but working file is
        restored (if missing), marked as conflicted, and contents
        carry conflict info.

'svn merge' pulls file modification atop missing file

  NOW:  "Skipped missing target" message.

  NEW:  

'svn merge' pulls file modification atop added file

  NOW:  Conflict!

  NEW:  Conflict!