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

Re: Tree conflict bug with switch

From: Stefan Sperling <stsp_at_elego.de>
Date: Wed, 30 Sep 2009 13:11:51 +0100

On Tue, Sep 29, 2009 at 02:15:46PM -0400, Mark Phippard wrote:
> I was sent the following problem description from one of our support
> team. I am also attaching a script I wrote which shows it. This
> seems like one of those cases where tree conflicts leaves your working
> copy in a state where you cannot really do anything. In this case, I
> am not sure what we should be doing. I kind of think this should not
> be a tree conflict at all and dir1 should just become unversioned and
> left on disk as we would have done prior to 1.6.

So you're saying we should disable tree conflict checking during
switch? I don't think that's a good idea.

> 1) create branchA off trunk
> 2) add dir1 with 4 files to branchA, commit
> 3) modify a file(file1.txt) under dir1 on branch A, DONT commit
> 4) do a switch from branch to trunk

It's clear that there is a conflicting local modification. Essentially,
the user was telling Subversion "I want this local mod for dir1/file1.txt
on this branch, ... er, no no wait a second I want it on trunk even though
dir1/file1.txt does not even yet exist on trunk".

That is a tree conflict, so flagging a tree conflict is correct.

> This will result in a tree conflict of dir1, as it does not exist on
> trunk. I want this dir so I choose to keep it durring the resolve.

So this dir should be in trunk as well as the in the branch.
Sounds like this is not a job for 'switch', but a job for merge.
Why not merge the dir, instead of switching and then adding?

> Now I have a directory that is scheduled to be added to trunk,
> with files that are still switched to the branch. I cannot commit the
> change I made to file1.txt as it will error out.

Suprisingly this commit works with a trunk build of Subversion.

Behaviour with 1.6.x (after running Mark's script):
$ svn status -v
                 3 1 stsp .
                 3 1 stsp MyProject
                 3 1 stsp MyProject/MyFolder
                 3 1 stsp MyProject/MyFolder/MyFile1.txt
                 3 1 stsp MyProject/MyFolder/MyFile2.txt
A + C - 3 stsp MyProject/MyFolder2
> local edit, incoming delete upon switch
M +S - 3 stsp MyProject/MyFolder2/MyFile1.txt
   +S - 3 stsp MyProject/MyFolder2/MyFile2.txt
   +S - 3 stsp MyProject/MyFolder2/MyFile3.txt
   +S - 3 stsp MyProject/MyFolder2/MyFile4.txt
$ svn info MyProject/MyFolder2/
Path: MyProject/MyFolder2
URL: file:///tmp/test/repos/trunk/MyProject/MyFolder2
Repository Root: file:///tmp/test/repos
Repository UUID: 2d370984-adb7-11de-bf72-a5207ae7fcd5
Revision: 3
Node Kind: directory
Schedule: add
Copied From URL: file:///tmp/test/repos/branches/r01/MyProject/MyFolder2
Copied From Rev: 3
Last Changed Author: stsp
Last Changed Rev: 3
Last Changed Date: 2009-09-30 12:48:32 +0100 (Wed, 30 Sep 2009)
Tree conflict: local edit, incoming delete upon switch
  Source left: (dir) file:///tmp/test/repos/branches/r01/MyProject/MyFolder2_at_3
  Source right: (none) file:///tmp/test/repos/trunk/MyProject/MyFolder2_at_3
$ svn info MyProject/MyFolder2/MyFile1.txt
Path: MyProject/MyFolder2/MyFile1.txt
Name: MyFile1.txt
URL: file:///tmp/test/repos/branches/r01/MyProject/MyFolder2/MyFile1.txt
Repository Root: file:///tmp/test/repos
Repository UUID: 2d370984-adb7-11de-bf72-a5207ae7fcd5
Revision: 3
Node Kind: file
Schedule: normal
Last Changed Author: stsp
Last Changed Rev: 3
Last Changed Date: 2009-09-30 12:48:32 +0100 (Wed, 30 Sep 2009)
Text Last Updated: 2009-09-30 12:48:32 +0100 (Wed, 30 Sep 2009)
Checksum: 7bd9c6096325cee2bcca1c1018b7c7b0
$ svn info MyProject/MyFolder2/MyFile2.txt
Path: MyProject/MyFolder2/MyFile2.txt
Name: MyFile2.txt
URL: file:///tmp/test/repos/branches/r01/MyProject/MyFolder2/MyFile2.txt
Repository Root: file:///tmp/test/repos
Repository UUID: 2d370984-adb7-11de-bf72-a5207ae7fcd5
Revision: 3
Node Kind: file
Schedule: normal
Last Changed Author: stsp
Last Changed Rev: 3
Last Changed Date: 2009-09-30 12:48:32 +0100 (Wed, 30 Sep 2009)
Text Last Updated: 2009-09-30 12:48:32 +0100 (Wed, 30 Sep 2009)
Checksum: 7bd9c6096325cee2bcca1c1018b7c7b0
$ svn resolve --accept=working MyProject/MyFolder2
Resolved conflicted state of 'MyProject/MyFolder2'
$ svn status -v
                 3 1 stsp .
                 3 1 stsp MyProject
                 3 1 stsp MyProject/MyFolder
                 3 1 stsp MyProject/MyFolder/MyFile1.txt
                 3 1 stsp MyProject/MyFolder/MyFile2.txt
A + - 3 stsp MyProject/MyFolder2
M +S - 3 stsp MyProject/MyFolder2/MyFile1.txt
   +S - 3 stsp MyProject/MyFolder2/MyFile2.txt
   +S - 3 stsp MyProject/MyFolder2/MyFile3.txt
   +S - 3 stsp MyProject/MyFolder2/MyFile4.txt
$ svn commit -m "commit"
  svn: Commit failed (details follow):
  svn: Did not expect '/tmp/test/wc/MyProject/MyFolder2/MyFile1.txt' to be a working copy root

However, the commit works with a Subversion trunk build:
$ svn status -v
                 3 1 stsp MyProject
                 3 1 stsp MyProject/MyFolder
                 3 1 stsp MyProject/MyFolder/MyFile1.txt
                 3 1 stsp MyProject/MyFolder/MyFile2.txt
A + C - 3 stsp MyProject/MyFolder2
> local edit, incoming delete upon switch
M + - 3 stsp MyProject/MyFolder2/MyFile1.txt
   + - 3 stsp MyProject/MyFolder2/MyFile2.txt
   + - 3 stsp MyProject/MyFolder2/MyFile3.txt
   + - 3 stsp MyProject/MyFolder2/MyFile4.txt
$ svn info MyProject/MyFolder2
Path: MyProject/MyFolder2
URL: file:///tmp/test/repos/trunk/MyProject/MyFolder2
Repository Root: file:///tmp/test/repos
Repository UUID: 2ada9bde-adb6-11de-8ef8-992b68a62679
Revision: 3
Node Kind: directory
Schedule: add
Copied From URL: file:///tmp/test/repos/branches/r01/MyProject/MyFolder2
Copied From Rev: 3
Last Changed Author: stsp
Last Changed Rev: 3
Last Changed Date: 2009-09-30 12:41:19 +0100 (Wed, 30 Sep 2009)
Tree conflict: local edit, incoming delete upon switch
  Source left: (dir) ^/branches/r01/MyProject/MyFolder2_at_3
  Source right: (none) ^/trunk/MyProject/MyFolder2_at_3
$ svn info MyProject/MyFolder2/MyFile1.txt
Path: MyProject/MyFolder2/MyFile1.txt
Name: MyFile1.txt
URL: file:///tmp/test/repos/trunk/MyProject/MyFolder2/MyFile1.txt
Repository Root: file:///tmp/test/repos
Repository UUID: d8739b9c-adb6-11de-9c56-e165c290dc79
Revision: 3
Node Kind: file
Schedule: normal
Last Changed Author: stsp
Last Changed Rev: 3
Last Changed Date: 2009-09-30 12:46:10 +0100 (Wed, 30 Sep 2009)
Text Last Updated: 2009-09-30 12:46:10 +0100 (Wed, 30 Sep 2009)
Checksum: 7bd9c6096325cee2bcca1c1018b7c7b0
$ svn info MyProject/MyFolder2/MyFile2.txt
Path: MyProject/MyFolder2/MyFile2.txt
Name: MyFile2.txt
URL: file:///tmp/test/repos/trunk/MyProject/MyFolder2/MyFile2.txt
Repository Root: file:///tmp/test/repos
Repository UUID: d8739b9c-adb6-11de-9c56-e165c290dc79
Revision: 3
Node Kind: file
Schedule: normal
Last Changed Author: stsp
Last Changed Rev: 3
Last Changed Date: 2009-09-30 12:46:10 +0100 (Wed, 30 Sep 2009)
Text Last Updated: 2009-09-30 12:46:10 +0100 (Wed, 30 Sep 2009)
Checksum: 7bd9c6096325cee2bcca1c1018b7c7b0
$ svn resolve --accept=working MyProject/MyFolder2
Resolved conflicted state of 'MyProject/MyFolder2'
$ svn status -v
                 3 1 stsp .
                 3 1 stsp MyProject
                 3 1 stsp MyProject/MyFolder
                 3 1 stsp MyProject/MyFolder/MyFile1.txt
                 3 1 stsp MyProject/MyFolder/MyFile2.txt
A + - 3 stsp MyProject/MyFolder2
M + - 3 stsp MyProject/MyFolder2/MyFile1.txt
   + - 3 stsp MyProject/MyFolder2/MyFile2.txt
   + - 3 stsp MyProject/MyFolder2/MyFile3.txt
   + - 3 stsp MyProject/MyFolder2/MyFile4.txt
$ svn commit -m "commit"
Adding MyProject/MyFolder2
Sending MyProject/MyFolder2/MyFile1.txt
Transmitting file data .
Committed revision 4.
$ svn log -v -r4 ^/
------------------------------------------------------------------------
r4 | stsp | 2009-09-30 12:44:03 +0100 (Wed, 30 Sep 2009) | 1 line
Changed paths:
   A /trunk/MyProject/MyFolder2 (from /branches/r01/MyProject/MyFolder2:3)
   M /trunk/MyProject/MyFolder2/MyFile1.txt

commit
------------------------------------------------------------------------

Note that trunk does not show 'S' notifications during 'svn status'.
Can anyone explain this?

> I can however just commit the 'add' of the new directory, but the
> files are still pointing to the branch, in fact I can then commit my
> change but it actually commits to the branch, not the trunk.

How? I cannot reproduce this:

$ svn resolved MyProject/MyFolder2
Resolved conflicted state of 'MyProject/MyFolder2'
$ svn st MyProject/MyFolder2
A + MyProject/MyFolder2
M +S MyProject/MyFolder2/MyFile1.txt
   +S MyProject/MyFolder2/MyFile2.txt
   +S MyProject/MyFolder2/MyFile3.txt
   +S MyProject/MyFolder2/MyFile4.txt
$ svn ci -mm MyProject/MyFolder2
svn: Commit failed (details follow):
svn: Did not expect '/tmp/test/wc/MyProject/MyFolder2/MyFile1.txt' to be a worki
ng copy root

>
> If I then delete the directory after adding it

How was it deleted?

In my testing with Mark's script, 'svn rm' does not allow me to delete it:

$ svn rm MyProject/MyFolder2/
svn: Use --force to override this restriction
svn: 'MyProject/MyFolder2' has local modifications

So it's likely that either --force, or something like rm -rf was used.
In the latter case, .svn dirs were blown away. If so, we can't expect
Subversion to do anything sane beyond this point.

> and update it pulls in
> the new directory and all the contents, all pointing to trunk (even
> though the files were never added).

Can we get more information on how this state really came about?
An amended shell script would be nice.

I cannot reproduce this with 1.6.x.

With svn rm --force:

$ svn resolved MyProject/MyFolder2
Resolved conflicted state of 'MyProject/MyFolder2'
$ svn add MyProject/MyFolder2
svn: warning: 'MyProject/MyFolder2' is already under version control
$ svn add MyProject/MyFolder2
$ svn rm MyProject/MyFolder2
svn: Use --force to override this restriction
svn: 'MyProject/MyFolder2' has local modifications
$ svn rm --force MyProject/MyFolder2
D MyProject/MyFolder2
$ svn up MyProject/MyFolder2
At revision 3.
$ svn status
$ ls MyProject/MyFolder2
ls: MyProject/MyFolder2: No such file or directory

With rm -rf:

$ rm -rf MyProject/MyFolder2
$ svn up
At revision 3.
$ svn up MyProject/MyFolder2
D MyProject/MyFolder2
Updated to revision 3.
$ svn status -v
                 3 1 stsp .
                 3 1 stsp MyProject
                 3 1 stsp MyProject/MyFolder
                 3 1 stsp MyProject/MyFolder/MyFile1.txt
                 3 1 stsp MyProject/MyFolder/MyFile2.txt
! + ? ? ? MyProject/MyFolder2

Given what we know so far, in my opinion, this is not a bug,
but a series of unfortunate events as follows:

A subcommand was used for a purpose it is not intended for (using 'svn
switch' to merge changes from one branch to another).
The user did not interpret warnings (in form of tree conflicts) correctly.
Subversion was then told to assume that the user knew what he was doing
(svn resolve --accept=working). From here on, I'm not sure what happened,
but it is possible that meta data was put into an inconsistent state by
running rm -rf on a directory. The resulting end state described as
"update pulls in the new directory and all the contents, all pointing to
trunk" is not reproducible from the given description.

Stefan

------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=462&dsMessageId=2402035
Received on 2009-09-30 14:12:31 CEST

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