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

current tree-conflicts branch status

From: Stefan Sperling <stsp_at_elego.de>
Date: Wed, 16 Jan 2008 17:37:13 +0100

Hello,

even though everyone has their heads wrapped around getting 1.5 out
the door, I'd like to report that Steve and I have gotten the tree
conflict branch to a milestone: Use cases 1 to 3 are now being handled
in a usable implementation.

Let me explain what this means in practice. Don't be afraid to read on
even if you've never heard of tree conflicts before.

I will try to describe what user-visible changes the tree-conflict
branch implements. Some of the following is copied and slightly adapted
from notes/tree-conflicts/use-cases.txt. See that file for reference
and some illustrative ASCII diagrams.

There are 3 use cases in which the tree-conflict branch's behaviour differs
from trunk's behaviour. I will illustrate the description of the first
use case with some commands and actual output so you can get a fairly good
idea of what the new behaviour looks like without having to checkout and
build the branch yourself. And if you want to see it for yourself no one
is stopping you from checking out the branch.

As usual, any feedback is welcome :)

Feedback on notes/tree-conflicts/detection.txt, which was recently committed
to trunk, would also be great. If you have the time to read it and have a
comment, we would like to hear from you.

-------------------

Use case 1:

   Developer A modifies Foo.c and commits it to the repository.

        $ cat Foo.c
        foo
        $ echo "Foo.c as modified by A" > Foo.c
        $ svn ci -m "modified Foo.c"

   Developer B has simultaneously moved Foo.c to Bar.c in his working
   copy.

        $ svn move Foo.c Bar.c
        A Bar.c
        D Foo.c
        $ svn ci -m "renamed Foo.c to Bar.c"
        Adding Bar.c
        Deleting Foo.c
        svn: Commit failed (details follow):
        svn: File '/Foo.c' is out of date
   
   B cannot commit because the working copy is out of date,
   so B runs 'svn update'.

This is what now happens on current trunk (old behaviour):

   The update will apply A's modifications to Foo.c in the
   repository to Foo.c in B's working copy.

        $ svn update
        U Foo.c
        Updated to revision 2.

   Note again that Foo.c is marked for deletion in B's working copy.
   So A's modification has been applied to a file marked as locally deleted.

   The 'U Foo.c' may have escaped B especially if the update touches a lot
   of files. B now does a commit.

        $ svn ci -m "renamed Foo.c to Bar.c"
        Adding Bar.c
        Deleting Foo.c

        Committed revision 3.

   A's modification of Foo.c will effectively be reverted by B's new
   revision. Foo.c will be deleted in the new revision, and Bar.c will be
   added with the content of the original Foo.c before A's modifications.
   Hence A will likely get angry with B.

   Had B run "svn diff" before committing, he may have seen this:

        $ svn diff Foo.c
        Index: Foo.c
        ===================================================================
        --- Foo.c (revision 2)
        +++ Foo.c (working copy)
        @@ -1 +0,0 @@
        -Foo.c as modified by A

This is what happens on the tree conflict branch instead (new behaviour):
   
   The update will apply A's modifications to Foo.c in the
   repository to Foo.c in B's working copy. It will also put
   the directory containing Foo.c into a state of conflict.

        $ svn update
        U Foo.c
        C .
        Updated to revision 2.

   Note again that Foo.c is marked for deletion in B's working copy.
   So A's modification has been applied to a file marked as locally deleted.

   B now tries to do a commit, but the commit fails.

        $ svn ci -m "renamed Foo.c to Bar.c"
        svn: Commit failed (details follow):
        svn: Aborting commit: '/tmp/wcB' remains in conflict

   (Here, /tmp/wcB happens to be the working copy root, but a tree conflict
   may be anchored at any directory in the working copy.)
   
   B can now run "svn info" on the tree-conflicted directory to inquire
   about the conflict, and decide what action to take to resolve it, possibly
   discussing the proper fix with A.

        $ svn info /tmp/wcB
        Path: /tmp/wcB
        URL: file:///tmp/repo
        Repository Root: file:///tmp/repo
        Repository UUID: eb86d84e-d4f0-407f-a0df-a893da9c5563
        Revision: 2
        Node Kind: directory
        Schedule: normal
        Last Changed Author: stsp
        Last Changed Rev: 2
        Last Changed Date: 2008-01-16 16:31:37 +0100 (Wed, 16 Jan 2008)
        Tree conflicts:
        The update edited the file 'Foo.c'.
        You have deleted 'Foo.c' locally.
        Maybe you renamed it?
   
   Note the last few lines in the output. (Whether this is the right
   place to put this information, and whether it has the right format
   is still open for debate. See http://svn.haxx.se/dev/archive-2008-01/0098.shtml)

   Once B has resolved the tree conflict, e.g. by moving the local
   modifications made to the locally deleted Foo.c to Bar.c, B runs
   "svn resolved" on the tree-conflicted directory.

        $ svn diff Foo.c
        Index: Foo.c
        ===================================================================
        --- Foo.c (revision 2)
        +++ Foo.c (working copy)
        @@ -1 +0,0 @@
        -Foo.c as modified by A
        $ cat Bar.c
        foo
        $ echo "Bar.c as modified by A" > Bar.c
        $ svn diff
        Index: Foo.c
        ===================================================================
        --- Foo.c (revision 2)
        +++ Foo.c (working copy)
        @@ -1 +0,0 @@
        -Foo.c as modified by A
        Index: Bar.c
        ===================================================================
        --- Bar.c (revision 1)
        +++ Bar.c (working copy)
        @@ -1 +1 @@
        -foo
        +Bar.c as modified by A
        
        Property changes on: Bar.c
        ___________________________________________________________________
        Added: svn:mergeinfo
        $ svn resolved /tmp/wcB
        Resolved conflicted state of '/tmp/wcB'
        
   B now does a commit. Barring no other conflicts (of any kind)
   the commit will succeed.

        $ svn ci -m "renamed Foo.c to Bar.c"
        Adding Bar.c
        Deleting Foo.c
        Transmitting file data .
        Committed revision 3.

-------------------

Use case 2:

   Developer B modifies Foo.c in his working copy.
   
   Developer A has simultaneously moved Foo.c to Bar.c and commits
   the move to the repository.

   B cannot commit because his working copy is out of date, so B runs
   'svn update'.

This is what now happens on current trunk (old behaviour):
   
   The update will add Bar.c (with the same content as the original Foo.c)
   to B's working copy, and delete Foo.c from B's working copy.
   Since B made local modifications to Foo.c, it will not be deleted from
   disk but left behind unversioned.

   B's source tree in the working copy likely builds fine because Foo.c
   is still present on disk.
 
   Assuming B does not notice that Foo.c fell out of version control,
   an incomplete change set may get committed, possibly breaking the tree.

This is what happens on the tree conflict branch instead (new behaviour):

   The update will add Bar.c (with the same content as the original Foo.c)
   to B's working copy, and delete Foo.c from B's working copy.

   The directory containing Foo.c will be put in a state of conflict.

   Since B made local modifications to Foo.c, it will not be deleted from
   disk but left behind unversioned.

   B's source tree in the working copy likely builds fine because Foo.c
   is still present on disk.

   B now tries to do a commit, but the commit fails because of the
   tree-conflicted directory.
 
   B can now run "svn info" on the tree-conflicted directory to inquire
   about the conflict, and decide what action to take to resolve it.

   Once B has resolved the tree conflict, B runs "svn resolved" on the
   tree-conflicted directory.

   B now does a commit. Barring no other conflicts (of any kind)
   the commit will succeed.

-------------------

Use case 3:

   Developer A moves Foo.c to Bar.c and commits the move to the repository.
   
   Developer B has moved Foo.c to Bix.c in his working copy.
   
   B cannot commit because his working copy is out of date, so B runs
   'svn update'.
   
This is what now happens on current trunk (old behaviour):

   The update will add Bar.c to B's working copy and
   delete Foo.c from B's working copy (the latter is a no-op).

   B now does a commit.

   After B's commit, the content of the original Foo.c will exist
   twice in the source tree under two different paths, namely Bar.c
   and Bix.c, respectively.
 
This is what happens on the tree conflict branch instead (new behaviour):

   The update will add Bar.c to B's working copy and
   delete Foo.c from B's working copy (the latter is a no-op).

   The directory containing Foo.c will be put in a state of conflict.

   B now tries to do a commit, but the commit fails because of the
   tree-conflicted directory.
 
   B can now run "svn info" on the tree-conflicted directory to inquire
   about the conflict, and decide what action to take to resolve it.

   Once B has resolved the tree conflict, B runs "svn resolved" on the
   tree-conflicted directory.

   B now does a commit. Barring no other conflicts (of any kind)
   the commit will succeed.

-- 
Stefan Sperling <stsp_at_elego.de>                 Software Developer
elego Software Solutions GmbH                            HRB 77719
Gustav-Meyer-Allee 25, Gebaeude 12        Tel:  +49 30 23 45 86 96 
13355 Berlin                              Fax:  +49 30 23 45 86 95
http://www.elego.de                 Geschaeftsfuehrer: Olaf Wagner

  • application/pgp-signature attachment: stored
Received on 2008-01-16 18:01:20 CET

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