You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Stefan Sperling <st...@elego.de> on 2008/11/14 13:43:24 UTC
State of tree conflict detection in trunk (for files)
Hi,
I took the time to run the tree-conflict scripts I've created for my
thesis (https://www.inf.fu-berlin.de/w/SE/ThesisTreeConflicts)
against current Subversion trunk (r34187).
These scripts provoke many different tree conflicts scenarios.
For the thesis I ran them with Subversion 1.5, and not a single
tree conflict was detected.
The results for current trunk however are most pleasing. Note that
I've only tested for files (since directories are, AFAIK, not the
main focus for 1.6).
I've noticed a few minor issues, see comments inline marked XXX.
I have not yet tested behaviour of subsequent update, revert, resolve,
and commit operations, but I am planning to do so later today and post
my results here.
I hope there won't be any more problems like the one Mark Phippard reported
in http://subversion.tigris.org/servlets/ReadMsg?listName=dev&msgNo=144666
but you never know. We had better catch them before release ;)
Anyone struggling to understand what is happening below will probably want
to refer to my scripts, which are included in this tarball inside the
'scripts/svn/' directory:
https://www.mi.fu-berlin.de/wiki/pub/SE/ThesisTreeConflicts/thesis-tree-conflicts.tar.gz
Plain http link: http://stsp.name/thesis-tree-conflicts.tar.gz
Now, on to the show:
=== svn-files-copy1-destroyed
Not detected -- file at copy target path is added,
file at copy source path is left destroyed.
$ svn st svn-files-copy1-destroyed/branch
M svn-files-copy1-destroyed/branch
D svn-files-copy1-destroyed/branch/alpha
A + svn-files-copy1-destroyed/branch/alpha.copied
=== svn-files-copy1-no-object
Not detected, item at copy target path is created unconditionally.
$ svn st svn-files-copy1-no-object/branch/
M svn-files-copy1-no-object/branch
A + svn-files-copy1-no-object/branch/eta.copied
=== svn-files-copy2-created
Detected.
--- Merging r2 through r3 into 'svn-files-copy2-created/branch':
C svn-files-copy2-created/branch/alpha.copied
Summary of conflicts:
Tree conflicts: 1
$ svn st svn-files-copy2-created/branch
M svn-files-copy2-created/branch
A C svn-files-copy2-created/branch/alpha.copied
$ svn info svn-files-copy2-created/branch/alpha.copied
[...]
Tree conflict:
The merge attempted to add 'alpha.copied'.
This action was obstructed by an item in the working copy.
=== svn-files-copy2-moved
Detected.
--- Merging r2 through r3 into 'svn-files-copy2-moved/branch':
C svn-files-copy2-moved/branch/alpha.copied
Summary of conflicts:
Tree conflicts: 1
$ svn st svn-files-copy2-moved/branch/
M svn-files-copy2-moved/branch
A + C svn-files-copy2-moved/branch/alpha.copied
D svn-files-copy2-moved/branch/beta
$ svn info svn-files-copy2-moved/branch/alpha.copied
[...]
Tree conflict:
The merge attempted to add 'alpha.copied'.
This action was obstructed by an item in the working copy.
=== svn-files-create-created
Detected.
--- Merging r2 through r3 into 'svn-files-create-created/branch':
C svn-files-create-created/branch/eta
Summary of conflicts:
Tree conflicts: 1
$ svn st svn-files-create-created/branch
M svn-files-create-created/branch
A C svn-files-create-created/branch/eta
$ svn info svn-files-create-created/branch/eta
[...]
Tree conflict:
The merge attempted to add 'eta'.
This action was obstructed by an item in the working copy.
=== svn-files-create-moved
Detected.
--- Merging r2 through r3 into 'svn-files-create-moved/branch':
C svn-files-create-moved/branch/eta
Summary of conflicts:
Tree conflicts: 1
$ svn st svn-files-create-moved/branch/
M svn-files-create-moved/branch
D svn-files-create-moved/branch/alpha
A + C svn-files-create-moved/branch/eta
$ svn info svn-files-create-moved/branch/eta
[...]
Tree conflict:
The merge attempted to add 'eta'.
This action was obstructed by an item in the working copy.
=== svn-files-destroy-modified
Detected.
--- Merging r2 through r4 into 'svn-files-destroy-modified/branch':
C svn-files-destroy-modified/branch/alpha
Summary of conflicts:
Tree conflicts: 1
$ svn st svn-files-destroy-modified/branch
M svn-files-destroy-modified/branch
C svn-files-destroy-modified/branch/alpha
$ svn info svn-files-destroy-modified/branch/alpha
[...]
Tree conflict:
The merge attempted to delete 'alpha'
(possibly as part of a rename operation).
Either you have edited 'alpha' locally, or it has been edited in the
history of the branch you are merging into, but those edits are not
present on the branch you are merging from.
=== svn-files-destroy-moved
Detected.
--- Merging r2 through r3 into 'svn-files-destroy-moved/branch/alpha':
C svn-files-destroy-moved/branch/alpha
Summary of conflicts:
Tree conflicts: 1
$ svn st svn-files-destroy-moved/branch
M svn-files-destroy-moved/branch
D C svn-files-destroy-moved/branch/alpha
A + svn-files-destroy-moved/branch/alpha.moved
$ svn info svn-files-destroy-moved/branch/alpha
[...]
Tree conflict:
The merge attempted to delete 'alpha'
(possibly as part of a rename operation).
You have deleted 'alpha' locally.
Maybe you renamed it?
=== svn-files-modify-destroyed
Detected.
--- Merging r2 through r3 into 'svn-files-modify-destroyed/branch/alpha':
C svn-files-modify-destroyed/branch/alpha
Summary of conflicts:
Tree conflicts: 1
$ svn st svn-files-modify-destroyed/branch
M svn-files-modify-destroyed/branch
D C svn-files-modify-destroyed/branch/alpha
$ svn info svn-files-modify-destroyed/branch/alpha
[...]
Tree conflict:
The merge attempted to edit 'alpha'.
'alpha' does not exist locally. Maybe you renamed it? Or has it been
renamed in the history of the branch you are merging into?
=== svn-files-modify-no-object
Detected.
--- Merging r4 into 'svn-files-modify-no-object/branch':
C svn-files-modify-no-object/branch/eta
Summary of conflicts:
Tree conflicts: 1
$ svn st svn-files-modify-no-object/branch
M svn-files-modify-no-object/branch
! C svn-files-modify-no-object/branch/eta
$ svn info svn-files-modify-no-object/branch/eta
[...]
Tree conflict:
The merge attempted to edit 'eta'.
'eta' does not exist locally. Maybe you renamed it? Or has it been
renamed in the history of the branch you are merging into?
=== svn-files-move1-destroyed
Detected.
--- Merging r2 through r3 into 'svn-files-move1-destroyed/branch':
A svn-files-move1-destroyed/branch/alpha.moved
--- Merging r2 through r3 into 'svn-files-move1-destroyed/branch/alpha':
C svn-files-move1-destroyed/branch/alpha
Summary of conflicts:
Tree conflicts: 1
$ svn st svn-files-move1-destroyed/branch
M svn-files-move1-destroyed/branch
D C svn-files-move1-destroyed/branch/alpha
A + svn-files-move1-destroyed/branch/alpha.moved
$ svn info svn-files-move1-destroyed/branch/alpha
[...]
Tree conflict:
The merge attempted to delete 'alpha'
(possibly as part of a rename operation).
You have deleted 'alpha' locally.
Maybe you renamed it?
=== svn-files-move1-moved
Detected.
--- Merging r2 through r3 into 'svn-files-move1-moved/branch':
A svn-files-move1-moved/branch/alpha.moved1
--- Merging r2 through r3 into 'svn-files-move1-moved/branch/alpha':
C svn-files-move1-moved/branch/alpha
Summary of conflicts:
Tree conflicts: 1
$ svn st svn-files-move1-moved/branch
M svn-files-move1-moved/branch
A + svn-files-move1-moved/branch/alpha.moved1
A + svn-files-move1-moved/branch/alpha.moved2
D C svn-files-move1-moved/branch/alpha
$ svn info svn-files-move1-moved/branch/alpha
[...]
Tree conflict:
The merge attempted to delete 'alpha'
(possibly as part of a rename operation).
You have deleted 'alpha' locally.
Maybe you renamed it?
=== svn-files-move1-no-object
Detected.
--- Merging r4 into 'svn-files-move1-no-object/branch':
A svn-files-move1-no-object/branch/eta.moved
C svn-files-move1-no-object/branch/eta
Summary of conflicts:
Tree conflicts: 1
$ svn st svn-files-move1-no-object/branch
M svn-files-move1-no-object/branch
! C svn-files-move1-no-object/branch/eta
A + svn-files-move1-no-object/branch/eta.moved
$ svn info svn-files-move1-no-object/branch/eta
[...]
Tree conflict:
The merge attempted to delete 'eta'
(possibly as part of a rename operation).
You have deleted 'eta' locally.
Maybe you renamed it?
XXX: Should say 'eta does not exist locally'.
=== svn-files-move2-created
Detected.
--- Merging r2 through r3 into 'svn-files-move2-created/branch':
C svn-files-move2-created/branch/alpha.moved
D svn-files-move2-created/branch/alpha
Summary of conflicts:
Tree conflicts: 1
$ svn st svn-files-move2-created/branch
M svn-files-move2-created/branch
D svn-files-move2-created/branch/alpha
A C svn-files-move2-created/branch/alpha.moved
$ svn info svn-files-move2-created/branch/alpha.moved
[...]
Tree conflict:
The merge attempted to add 'alpha.moved'.
This action was obstructed by an item in the working copy.
XXX: Should say 'attempted to either newly add alpha.moved
or copy or move another file to this location'.
=== svn-files-move2-moved
Detected:
--- Merging r2 through r3 into 'svn-files-move2-moved/branch':
C svn-files-move2-moved/branch/alpha.moved
D svn-files-move2-moved/branch/alpha
Summary of conflicts:
Tree conflicts: 1
$ svn st svn-files-move2-moved/branch/
M svn-files-move2-moved/branch
D svn-files-move2-moved/branch/alpha
D svn-files-move2-moved/branch/beta
A + C svn-files-move2-moved/branch/alpha.moved
$ svn info svn-files-move2-moved/branch/alpha.moved
[...]
Tree conflict:
The merge attempted to add 'alpha.moved'.
This action was obstructed by an item in the working copy.
XXX: See XXX for svn-files-move2-created. Applies here, too.
Stefan
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Re: State of tree conflict detection in trunk (for directories)
Posted by Stefan Sperling <st...@elego.de>.
On Sun, Nov 16, 2008 at 11:10:41PM +0100, Branko ??ibej wrote:
> Stefan Sperling wrote:
> > On Fri, Nov 14, 2008 at 01:43:24PM +0000, Stefan Sperling wrote:
> >
> >> Hi,
> >>
> >> I took the time to run the tree-conflict scripts I've created for my
> >> thesis (https://www.inf.fu-berlin.de/w/SE/ThesisTreeConflicts)
> >> against current Subversion trunk (r34187).
> >>
> >> These scripts provoke many different tree conflicts scenarios.
> >> For the thesis I ran them with Subversion 1.5, and not a single
> >> tree conflict was detected.
> >>
> >
> > Same story (i.e. tree conflict *detection* only) for directories,
> > using trunk build from r34234.
> >
>
> What I'd really like to know: Is detection without resolution useful in
> real life?
You're in the wrong thread.
This one is only here to highlight our success in detection which
is still important in its own right, even though resolution may
still suck.
See here:
http://subversion.tigris.org/servlets/ReadMsg?listName=dev&msgNo=145390
And here:
http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=145339
> What can the user do if SVN detects the conflict but she
> can't resolve it?
You can help us find out, e.g. by walking through a few scenarios :)
Stefan
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Re: State of tree conflict detection in trunk (for directories)
Posted by Branko Čibej <br...@xbc.nu>.
Stefan Sperling wrote:
> On Fri, Nov 14, 2008 at 01:43:24PM +0000, Stefan Sperling wrote:
>
>> Hi,
>>
>> I took the time to run the tree-conflict scripts I've created for my
>> thesis (https://www.inf.fu-berlin.de/w/SE/ThesisTreeConflicts)
>> against current Subversion trunk (r34187).
>>
>> These scripts provoke many different tree conflicts scenarios.
>> For the thesis I ran them with Subversion 1.5, and not a single
>> tree conflict was detected.
>>
>
> Same story (i.e. tree conflict *detection* only) for directories,
> using trunk build from r34234.
>
What I'd really like to know: Is detection without resolution useful in
real life? What can the user do if SVN detects the conflict but she
can't resolve it?
-- Brane
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Re: State of tree conflict detection in trunk (for directories)
(was: same for files)
Posted by Stefan Sperling <st...@elego.de>.
On Fri, Nov 14, 2008 at 01:43:24PM +0000, Stefan Sperling wrote:
> Hi,
>
> I took the time to run the tree-conflict scripts I've created for my
> thesis (https://www.inf.fu-berlin.de/w/SE/ThesisTreeConflicts)
> against current Subversion trunk (r34187).
>
> These scripts provoke many different tree conflicts scenarios.
> For the thesis I ran them with Subversion 1.5, and not a single
> tree conflict was detected.
Same story (i.e. tree conflict *detection* only) for directories,
using trunk build from r34234.
I am happy to announce that Subversion now detects more tree conflicts
than Mercurial and Git combined:
svn: 21, hg: 4, git: 15
The svn count is from mails in this thread.
Subversion 1.5 would detect NO tree conflicts at all.
See thesis paper linked above for were git and hg numbers come from.
Note that for hg and git, tree conflicts treated as text conflicts
were not counted. Do not take these numbers too seriously, they
are not universal indicators of the quality of any particular system.
While svn can detect 21 and possibly more tree conflicts, we still have
to improve the resolving part.
See http://subversion.tigris.org/servlets/ReadMsg?listName=dev&msgNo=145339
Now, here's what detection currently look like for directories:
=== svn-directories-copy1-destroyed
Not detected (not detected for files either)
--- Merging r2 through r3 into 'svn-directories-copy1-destroyed/branch':
A svn-directories-copy1-destroyed/branch/gamma.copied
A svn-directories-copy1-destroyed/branch/gamma.copied/delta
$ svn status svn-directories-copy1-destroyed/branch
M svn-directories-copy1-destroyed/branch
D svn-directories-copy1-destroyed/branch/gamma
D svn-directories-copy1-destroyed/branch/gamma/delta
A + svn-directories-copy1-destroyed/branch/gamma.copied
A + svn-directories-copy1-destroyed/branch/gamma.copied/delta
=== svn-directories-copy1-no-object
Not detected (not detected for files either)
--- Merging r4 into 'svn-directories-copy1-no-object/branch':
A svn-directories-copy1-no-object/branch/eta.copied
$ svn status svn-directories-copy1-no-object/branch
M svn-directories-copy1-no-object/branch
A + svn-directories-copy1-no-object/branch/eta.copied
=== svn-directories-copy2-created
Not detected (detected for files!)
--- Merging r2 through r3 into 'svn-directories-copy2-created/branch':
C svn-directories-copy2-created/branch/gamma.copied
Summary of conflicts:
Tree conflicts: 1
$ svn status svn-directories-copy2-created/branch
M svn-directories-copy2-created/branch
A C svn-directories-copy2-created/branch/gamma.copied
A svn-directories-copy2-created/branch/gamma.copied/iota
=== svn-directories-copy2-moved
Detected.
--- Merging r2 through r3 into 'svn-directories-copy2-moved/branch':
C svn-directories-copy2-moved/branch/gamma.copied
Summary of conflicts:
Tree conflicts: 1
$ svn status svn-directories-copy2-moved/branch
M svn-directories-copy2-moved/branch
A + C svn-directories-copy2-moved/branch/gamma.copied
D svn-directories-copy2-moved/branch/epsilon
D svn-directories-copy2-moved/branch/epsilon/zeta
$ svn info svn-directories-copy2-moved/branch/gamma.copied
[...]
Tree conflict:
The merge attempted to add 'gamma.copied'.
Either you have added 'gamma.copied' locally, or it has been added in the
history of the branch you are merging into.
=== svn-directories-create-created
Detected.
--- Merging r2 through r3 into 'svn-directories-create-created/branch':
C svn-directories-create-created/branch/eta
Summary of conflicts:
Tree conflicts: 1
$ svn status svn-directories-create-created/branch
M svn-directories-create-created/branch
A C svn-directories-create-created/branch/eta
A svn-directories-create-created/branch/eta/theta
$ svn info svn-directories-create-created/branch/eta
[...]
Tree conflict:
The merge attempted to add 'eta'.
Either you have added 'eta' locally, or it has been added in the
history of the branch you are merging into.
=== svn-directories-create-moved
Detected.
--- Merging r2 through r3 into 'svn-directories-create-moved/branch':
C svn-directories-create-moved/branch/eta
Summary of conflicts:
Tree conflicts: 1
$ svn status svn-directories-create-moved/branch
M svn-directories-create-moved/branch
D svn-directories-create-moved/branch/gamma
D svn-directories-create-moved/branch/gamma/delta
A + C svn-directories-create-moved/branch/eta
$ svn info svn-directories-create-moved/branch/eta
[...]
Tree conflict:
The merge attempted to add 'eta'.
Either you have added 'eta' locally, or it has been added in the
history of the branch you are merging into.
=== svn-directories-destroy-modified
Not detected (detected for files!)
--- Merging r2 through r4 into 'svn-directories-destroy-modified/branch':
D svn-directories-destroy-modified/branch/gamma
$ svn status svn-directories-destroy-modified/branch
M svn-directories-destroy-modified/branch
D svn-directories-destroy-modified/branch/gamma
D svn-directories-destroy-modified/branch/gamma/delta
D svn-directories-destroy-modified/branch/gamma/iota
=== svn-directories-destroy-moved
Detected.
--- Merging r2 through r4 into 'svn-directories-destroy-moved/branch':
C svn-directories-destroy-moved/branch/gamma
Summary of conflicts:
Tree conflicts: 1
$ svn status svn-directories-destroy-moved/branch
M svn-directories-destroy-moved/branch
! C svn-directories-destroy-moved/branch/gamma
$ svn info svn-directories-destroy-moved/branch/gamma
[...]
Tree conflict:
The merge attempted to delete 'gamma',
or attempted to rename it.
You have deleted 'gamma' locally.
Maybe you renamed it?
=== svn-directories-move1-destroyed
Detected.
--- Merging r2 through r3 into 'svn-directories-move1-destroyed/branch':
A svn-directories-move1-destroyed/branch/gamma.moved
A svn-directories-move1-destroyed/branch/gamma.moved/delta
--- Merging r2 through r3 into 'svn-directories-move1-destroyed/branch/gamma':
C svn-directories-move1-destroyed/branch/gamma
Summary of conflicts:
Tree conflicts: 1
$ svn status svn-directories-move1-destroyed/branch
M svn-directories-move1-destroyed/branch
D C svn-directories-move1-destroyed/branch/gamma
D svn-directories-move1-destroyed/branch/gamma/delta
A + svn-directories-move1-destroyed/branch/gamma.moved
A + svn-directories-move1-destroyed/branch/gamma.moved/delta
$ svn info svn-directories-move1-destroyed/branch/gamma
[...]
Tree conflict:
The merge attempted to delete 'gamma',
or attempted to rename it.
You have deleted 'gamma' locally.
Maybe you renamed it?
=== svn-directories-move1-moved
Detected.
--- Merging r2 through r3 into 'svn-directories-move1-moved/branch':
A svn-directories-move1-moved/branch/gamma.moved1
A svn-directories-move1-moved/branch/gamma.moved1/delta
--- Merging r2 through r3 into 'svn-directories-move1-moved/branch/gamma':
C svn-directories-move1-moved/branch/gamma
Summary of conflicts:
Tree conflicts: 1
$ svn status svn-directories-move1-moved/branch
M svn-directories-move1-moved/branch
D C svn-directories-move1-moved/branch/gamma
D svn-directories-move1-moved/branch/gamma/delta
A + svn-directories-move1-moved/branch/gamma.moved1
A + svn-directories-move1-moved/branch/gamma.moved1/delta
A + svn-directories-move1-moved/branch/gamma.moved2
$ svn info svn-directories-move1-moved/branch/gamma
[...]
Tree conflict:
The merge attempted to delete 'gamma',
or attempted to rename it.
You have deleted 'gamma' locally.
Maybe you renamed it?
=== svn-directories-move1-no-object
Not detected (detected for files!)
--- Merging r4 into 'svn-directories-move1-no-object/branch':
A svn-directories-move1-no-object/branch/eta.copied
$ svn status svn-directories-move1-no-object/branch
M svn-directories-move1-no-object/branch
A + svn-directories-move1-no-object/branch/eta.copied
=== svn-directories-move2-created
Detected.
--- Merging r2 through r3 into 'svn-directories-move2-created/branch':
C svn-directories-move2-created/branch/gamma.moved
D svn-directories-move2-created/branch/gamma
Summary of conflicts:
Tree conflicts: 1
$ svn status svn-directories-move2-created/branch
M svn-directories-move2-created/branch
D svn-directories-move2-created/branch/gamma
D svn-directories-move2-created/branch/gamma/delta
A C svn-directories-move2-created/branch/gamma.moved
A svn-directories-move2-created/branch/gamma.moved/iota
$ svn info svn-directories-move2-created/branch/gamma.moved
[...]
Tree conflict:
The merge attempted to add 'gamma.moved'.
Either you have added 'gamma.moved' locally, or it has been added in the
history of the branch you are merging into.
=== svn-directories-move2-moved
Detected.
--- Merging r2 through r3 into 'svn-directories-move2-moved/branch':
C svn-directories-move2-moved/branch/gamma.moved
D svn-directories-move2-moved/branch/gamma
Summary of conflicts:
Tree conflicts: 1
$ svn status svn-directories-move2-moved/branch
M svn-directories-move2-moved/branch
D svn-directories-move2-moved/branch/gamma
D svn-directories-move2-moved/branch/gamma/delta
D svn-directories-move2-moved/branch/epsilon
D svn-directories-move2-moved/branch/epsilon/zeta
A + C svn-directories-move2-moved/branch/gamma.moved
$ svn info svn-directories-move2-moved/branch/gamma.moved
[...]
Tree conflict:
The merge attempted to add 'gamma.moved'.
Either you have added 'gamma.moved' locally, or it has been added in the
history of the branch you are merging into.
===
Stefan
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Re: tree conflicts from user's point of view
Posted by "Neels J. Hofmeyr" <ne...@elego.de>.
Stefan Sperling wrote:
> On Fri, Nov 14, 2008 at 01:43:24PM +0000, Stefan Sperling wrote:
>> Hi,
>>
>> I took the time to run the tree-conflict scripts I've created for my
>> thesis (https://www.inf.fu-berlin.de/w/SE/ThesisTreeConflicts)
>> against current Subversion trunk (r34187).
[...]
> In case you've missed the previous mail in this thread, the scripts
> used to create the example tree conflict scenarios used below are
> inside this tarball:
> https://www.mi.fu-berlin.de/wiki/pub/SE/ThesisTreeConflicts/thesis-tree-conflicts.tar.gz
>
> === svn-files-copy2-created
>
> In this case, we are merging from trunk into a branch,
> and are confronted with the following tree conflict:
>
> $ svn status
> M .
> A C alpha.copied
> $ svn info alpha.copied
> [...]
> Tree conflict:
> The merge attempted to add 'alpha.copied'.
> This action was obstructed by an item in the working copy.
> $
>
> By the way, I don't like having to run "svn info <victim>" here,
> and there's no indication from svn to the user that this is what
> she should be doing. "svn info" just does not feel like a tool to
> query conflict-type information, since it has historically never
> been used for this purpose, and it prints lots of irrelevant
> information that I've omitted from the transcript above.
>
> I'd rather type something like 'svn status --human-readable'
> with an alias for that which goes 'svn status -h' in order
> to get at the human readable conflict description.
>
> Also, we should continue this thread and enhance 'svn status'
> to summarise the nature of the tree conflict, so that advanced
> users can skip the human readable messages altogether:
> http://subversion.tigris.org/servlets/ReadMsg?listName=dev&msgNo=144323
+1!
>
> Now, let's try to get rid of this conflict. So the problem is
> that the merge tried to copy a file to a location where I've
> locally created a file. Let's assume I'm fine with my file
> being called something else, and as a first step towards
> resolving the conflict, I move my file out of the way:
>
> $ svn mv alpha.copied alpha.copied2
> A alpha.copied2
> D alpha.copied
> $
>
> The tree conflict is still recorded:
> $ svn st
> M .
> ! C alpha.copied
> A alpha.copied2
> $
>
> The commit succeeds nonetheless:
>
> $ svn commit -m "commit anyway"
> Sending . <---(mergeinfo)
> Adding alpha.copied2
> Transmitting file data .
> Committed revision 4.
> $
>
> Huh... Do we want to allow this?
We are allowing commits of *siblings* of tree-conflicts.
Technically, alpha.copied2 has nothing to do with the tree-conflict.
But why doesn't this print an error on the conflicted item? Probably because
a commit is skipping missing items.
Then again, a commit would bail out completely if failing on one of its
targets. So it's a bug. Don't skip tree-conflicted missing items upon commit.
>
> The conflict is still recorded ...
>
> $ svn st
> ! C alpha.copied
> $
>
> ... but the mergeinfo got committed before the conflict was resolved.
ohje...
>
> OK, so let's try to merge the copy again anyway. I'm a smart user so
> I realise the mergeinfo which is now on my top-level branch directory
> will prevent me from merging the copy (which my branch does not have yet)
> into my branch again:
>
> $ svn mergeinfo --show-revs=eligible ^/trunk
> $
>
> So let's first do a record-only reverse-merge (i.e. this is the part
> where your typical "I never use branches anyway" user is gonna run away
> screaming). We check the log (hey wasn't merging supposed to be
> automatic?) and find out that the copy was made in r3, so we run:
>
> $ svn merge --record-only -r3:2 ^/trunk
> $ svn diff
>
> Property changes on: .
> ___________________________________________________________________
> Modified: svn:mergeinfo
> Reverse-merged /trunk:r3
>
> $
>
> OK, now we can merge the copy again, there's nothing in the way:
>
> $ svn merge ^/trunk
> --- Merging r3 through r4 into '.':
> A alpha.copied
> $ svn status
> M .
> A + C alpha.copied
> $
> $ svn resolved alpha.copied
> Resolved conflicted state of 'alpha.copied'
> $ svn status
> M .
> A + alpha.copied
>
> So now I have both new files at different paths, which is what I wanted.
> I can commit the desired merge result:
>
> $ ls
> alpha alpha.copied alpha.copied2 beta epsilon/ gamma
> $ svn ci -m "resolved tree conflict on alpha.copied"
> Sending .
> Adding alpha.copied
>
> Committed revision 5.
So far so good, but fixing the commit to notice the tree-conflict would cut
the detour from the middle and make this a lot smoother.
>
>
> === svn-files-destroy-modified
>
> This is a popular case: Someone on trunk removed a file
> that I've modified on the branch:
>
> $ svn status
> M .
> C alpha
> $ svn info alpha
> [...]
> Tree conflict:
> The merge attempted to delete 'alpha'
> (possibly as part of a rename operation).
> Either you have edited 'alpha' locally, or it has been edited in the
> history of the branch you are merging into, but those edits are not
> present on the branch you are merging from.
Er, shouldn't that be: ", but this node has been deleted in the branch you
are merging from" ?
>
> ^ The indentation seems off here. (Oh, in fact, it's off in other cases, too.)
>
> First gut reaction: Is my file still there?
>
> $ cat alpha
> alpha, but modified
phew.
>
> OK, it is. Now, I don't know yet who was trying to remove the file
> and why, but I'm going to find out. Actually, I have to go find out
> because the file may have been moved somewhere else! So I go browse
> the log, and find out the file has indeed been deleted.
>
> After some discussion with other developers we decide to keep the
> file in place on the branch. So all I have to do is this:
>
> $ svn resolve --accept=mine-full alpha
> Resolved conflicted state of 'alpha'
> $ svn status
> M .
> $
>
> Great, issue settled.
>
> $ svn ci -m "sync branch with trunk"
> Sending .
> subversion/libsvn_client/commit.c:860: (apr_err=160028)
> svn: Commit failed (details follow):
> subversion/libsvn_repos/commit.c:124: (apr_err=160028)
> svn: Directory '/branch' is out of date
>
> Huh? Why that?
Hm, resolve probably fails to step up some revision number.
>
> $ svn up
> At revision 4.
> $ svn ci -m "sync branch with trunk"
> Sending .
>
> Committed revision 5.
> $
>
> As a user, I don't really grok why the commit failed the first time
> around since the update apparently did nothing, but I'm happy to know
> that my data made it into the repository the second time. I go home
> from work and hope svn won't play such weird tricks on me again tomorrow.
> Maybe I'm just seeing things...
>
> As a developer, I'm asking myself whether this is related to us
> not updating text-bases in some cases? If so, shouldn't the UI
> indicate that this has happened?
I have no idea, but I would expect `resolve' to take care of everything for me.
>
>
> === svn-files-move1-moved
>
> This is an all-time favourite and actually one of the most likely
> tree conflict cases. Two teams do refactoring and happen to end
> up doing divergent renames of the same file:
>
> $ svn status
> M .
> A + alpha.moved1
> A + alpha.moved2
> D C alpha
> $ svn info alpha
> [...]
> Tree conflict:
> The merge attempted to delete 'alpha'
> (possibly as part of a rename operation).
> You have deleted 'alpha' locally.
> Maybe you renamed it?
>
> Looking at the logs and status output, I figure out what happened.
> I escalate this high-priority problem to the head of department,
> who decides to hold a developer meeting instantly in order to settle
> the dispute. After much bikeshedding and coffee I finally give up
> and we "agree" on the other team's stupid filename, alpha.moved1.
heh
>
> So I diff the files -- renames often go along with internal changes,
> but luckily in this case, the files remained the same.
>
> $ svn diff alpha.moved1 alpha.moved2
> $ svn rm alpha.moved2
> subversion/svn/util.c:864: (apr_err=195006)
> svn: Use --force to override this restriction
> subversion/libsvn_client/delete.c:65: (apr_err=195006)
> svn: 'alpha.moved2' has local modifications
> $ svn diff alpha.moved2
> $
Weird. Might that again be that alpha.moved2 is still considered to be at an
earlier revision?
>
> Huh? I never modified the file locally as far as I know,
> but let's try using the force:
>
> $ svn rm --force alpha.moved2
> D alpha.moved2
> $
>
> OK, seems to have worked. Now let's resolve:
>
> $ svn resolve --accept=working alpha
> Resolved conflicted state of 'alpha'
> $ svn status
> M .
> A + alpha.moved1
> D alpha
> $
>
> That was it!
>
> The above is a bit unrealistic. In real life, renaming files and
> file modifications often must go together (e.g. when refactoring
> Java classes, or when changing references to things in other
> files which were also renamed), so people will want to merge
> the files textually.
>
> Let's repeat, and patch the scenario script so that we have textual
> modifications in both renamed files:
>
> --- svn-files-move1-moved.sh.orig Fri Nov 14 17:40:19 2008
> +++ svn-files-move1-moved.sh Fri Nov 14 17:41:05 2008
> @@ -5,10 +5,14 @@
>
> # Move a file in trunk
> svn move $trunk/alpha $trunk/alpha.moved1
> +# Do a text mod:
> +echo "alpha.moved1" > $trunk/alpha.moved1
> svn commit -m "moved alpha" $trunk
>
> # Move the same file to a different path in the branch
> svn move $branch/alpha $branch/alpha.moved2
> +# Do a text mod:
> +echo "alpha.moved2" > $branch/alpha.moved2
> # Committing here does not affect the merge result
>
> # Merge the rename into the branch
>
> $ svn status
> M .
> A + alpha.moved1
> A + alpha.moved2
> D C alpha
> $ svn info alpha
> [...]
> Tree conflict:
> The merge attempted to delete 'alpha'
> (possibly as part of a rename operation).
> You have deleted 'alpha' locally.
> Maybe you renamed it?
>
> So this time, the textual modifications add to the problem:
>
> $ diff -u alpha.moved1 alpha.moved2
> --- alpha.moved1 Fri Nov 14 17:46:18 2008
> +++ alpha.moved2 Fri Nov 14 17:46:18 2008
> @@ -1 +1 @@
> -alpha.moved1
> +alpha.moved2
>
> Now, as a naive user, I try the following trick: I revert the merge,
> rename the file to match the name on trunk, re-apply my textual
> modifications (they've not yet been committed either as I made them
> in the same go as the rename), and merge again. That should give me
> a text conflict on the file, right?
>
> We save the local textmods in /tmp/alpha1.diff, conveniently piping
> "svn diff" output through sed to fix up the destination path in the diff:
>
> $ svn diff alpha.moved1 alpha.moved2 \
> | sed -e 's/^\(+++ alpha.\)moved2/\1moved1/' > /tmp/alpha.moved1.diff
> $ cat /tmp/alpha.moved1.diff
> Index: alpha.moved2
> ===================================================================
> --- alpha.moved2 (revision 2)
> +++ alpha.moved1 (working copy)
> @@ -1 +1 @@
> -alpha
> +alpha.moved2
>
> Now, on to the remaining steps:
>
> $ svn revert -R .
> Reverted '.'
> Reverted 'alpha.moved1'
> Reverted 'alpha.moved2'
> Reverted 'alpha'
> $ svn status
> ? alpha.moved1
> ? alpha.moved2
> $ rm alpha.moved[12]
> $ svn status
It would yield simpler results to merge in trunk at this point and apply the
patch afterwards [1]. But let's see what happens.
> $ svn mv alpha alpha.moved1
> A alpha.moved1
> D alpha
> $ patch -p0 < /tmp/alpha.moved1.diff
> Hmm... Looks like a unified diff to me...
> The text leading up to this was:
> --------------------------
> |Index: alpha.moved2
> |===================================================================
> |--- alpha.moved2 (revision 2)
> |+++ alpha.moved1 (working copy)
> --------------------------
> Patching file alpha.moved1 using Plan A...
> Hunk #1 succeeded at 1.
> done
> $ svn diff
> Index: alpha.moved1
> ===================================================================
> --- alpha.moved1 (revision 2)
> +++ alpha.moved1 (working copy)
> @@ -1 +1 @@
> -alpha
> +alpha.moved2
The thing here is that in the case of a Java rename, if the filename is now
alpha.moved1, the class name would now also have to be alpha.moved1 and not
*2. Nevertheless, it's better to play through conflicting changes.
> Index: alpha
> ===================================================================
> --- alpha (revision 2)
> +++ alpha (working copy)
> @@ -1 +0,0 @@
> -alpha
> $ svn merge ^/trunk
> --- Merging r2 through r3 into '.':
> C alpha.moved1
> --- Merging r2 through r3 into 'alpha':
> C alpha
> Summary of conflicts:
> Tree conflicts: 2
>
> Hell's bells, the tree conflicts just multiplied!
>
> $ svn status
> M .
> ? alpha.moved1.orig
> A + C alpha.moved1
> D C alpha
>
> $ svn info alpha.moved1
> [...]
> Tree conflict:
> The merge attempted to add 'alpha.moved1'.
> This action was obstructed by an item in the working copy.
> $ svn info alpha
> [...]
> Tree conflict:
> The merge attempted to delete 'alpha'
> (possibly as part of a rename operation).
> You have deleted 'alpha' locally.
> Maybe you renamed it?
Hm, that may seem pretty dumb to users out there. But not doing this would
abandon the D->D and A->A tree-conflicts. Even with proper move information,
this would still have to be a Move->Move tree-conflict.
>
> So there seems to be no way to make subversion treat the
> scenario as a text conflict. Let's try a different route,
> make a backup of our file, remove it from version control,
> and re-run the merge.
How about just running `resolved' on the two conflicts instead and mending
the situation manually? [2]
>
> $ svn revert -R .
> Reverted '.'
> Reverted 'alpha.moved1'
> Reverted 'alpha'
> $ svn status
> ? alpha.moved1.orig
Why doesn't alpha.moved1 show up here? Didn't we revert everything? It
*said* "Reverted 'alpha.moved1', and according to `ls' below, it is still
around.
> $ cat alpha.moved1.orig
> alpha
> $ rm alpha.moved1.orig
> $ ls
> alpha.moved1 beta epsilon/ gamma/
> $ cat alpha.moved1
> alpha.moved2
> $ cat /tmp/alpha.moved2.diff
> Index: alpha.moved2
> ===================================================================
> --- alpha.moved2 (revision 2)
> +++ alpha.moved2 (working copy)
> @@ -1 +1 @@
> -alpha
> +alpha.moved2
> $ cp alpha.moved1 alpha.moved1.mine
> $ svn rm alpha.moved1
> D alpha.moved1
> $ svn merge ^/trunk
> --- Merging r2 through r4 into 'alpha.moved1':
> A alpha.moved1
> --- Merging r2 through r4 into '.':
> C alpha
> Summary of conflicts:
> Tree conflicts: 1
> $ ls
> alpha.moved1 alpha.moved1.mine beta epsilon/ gamma/
This is a little more complex than it needs to be. But it nevertheless is a
situation people may end up with.
>
> Now we manually merge alpha.moved1 and alpha.moved1.mine, which for
> sake of argument, results in:
>
> $ cat alpha.moved1
> alpha.moved1
> alpha.moved2
>
> We're now left with a single tree conflict on alpha,
> which we can safely mark as resolved:
>
> $ rm alpha.moved1.mine
> $ ls
> alpha.moved1 beta epsilon/ gamma/
> $ svn status
> M .
> ! C alpha
> R + alpha.moved1
> $ svn resolved alpha
> Resolved conflicted state of 'alpha'
> $ svn status
> M .
> R + alpha.moved1
>
> The alpha.moved1 on the branch has now been replaced with
> its counterpart on trunk, and it includes local changes
> made to it on the branch.
>
> Before we can commit, the spurious out-of-date problem
> comes up again:
>
> $ svn commit -m "synced branch with trunk"
> Sending .
> subversion/libsvn_client/commit.c:860: (apr_err=160028)
> svn: Commit failed (details follow):
> subversion/libsvn_repos/commit.c:124: (apr_err=160028)
> svn: Directory '/branch' is out of date
> $ svn update
> At revision 4.
> $ svn commit -m "synced branch with trunk"
> Sending .
> Replacing alpha.moved1
> Transmitting file data .
> Committed revision 5.
Well, I don't get why this would be a "Replace". Actually, it should just be
a "merge trunk to my branch and apply text changes that I've stored away
before". This related to my question above about alpha.moved1 not being
reverted although the output stated that it was.
[1], [2]: Would you mind playing through these two variants as well?
>
>
> That's it for now. I might look into more cases another time.
Thanks! It's great to see stuff like this. These cases should become new
cmdline tests once the behaviour is settled.
~Neels
>
> It seems like handling tree conflicts is not going to be easy for users.
> In any case, resolving these conflicts requires quite a bit of patience
> and skill from the user. Given the complexity of the problem, this does
> not surprise me. I hope, however, that we can make further improvements
> to the UI to make the resolution process a bit more straightforward,
> if possible.
>
> Comments, ideas?
>
> Thanks,
> Stefan
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
> For additional commands, e-mail: dev-help@subversion.tigris.org
>
tree conflicts from user's point of view (was: State of tree
conflict detection in trunk (for files))
Posted by Stefan Sperling <st...@elego.de>.
On Fri, Nov 14, 2008 at 01:43:24PM +0000, Stefan Sperling wrote:
> Hi,
>
> I took the time to run the tree-conflict scripts I've created for my
> thesis (https://www.inf.fu-berlin.de/w/SE/ThesisTreeConflicts)
> against current Subversion trunk (r34187).
>
> These scripts provoke many different tree conflicts scenarios.
> For the thesis I ran them with Subversion 1.5, and not a single
> tree conflict was detected.
>
> The results for current trunk however are most pleasing. Note that
> I've only tested for files (since directories are, AFAIK, not the
> main focus for 1.6).
>
> I've noticed a few minor issues, see comments inline marked XXX.
>
> I have not yet tested behaviour of subsequent update, revert, resolve,
> and commit operations, but I am planning to do so later today and post
> my results here.
Right, so I've played around with this a bit, in order to get a feel
what the current user experience is like, and what kind of background
knowledge and skills our current UI is expecting from users to be able
to deal with tree conflicts.
I have not gotten around to try all cases I have scripts for, but I
hope what I've written below will be helpful anyway.
In case you've missed the previous mail in this thread, the scripts
used to create the example tree conflict scenarios used below are
inside this tarball:
https://www.mi.fu-berlin.de/wiki/pub/SE/ThesisTreeConflicts/thesis-tree-conflicts.tar.gz
=== svn-files-copy2-created
In this case, we are merging from trunk into a branch,
and are confronted with the following tree conflict:
$ svn status
M .
A C alpha.copied
$ svn info alpha.copied
[...]
Tree conflict:
The merge attempted to add 'alpha.copied'.
This action was obstructed by an item in the working copy.
$
By the way, I don't like having to run "svn info <victim>" here,
and there's no indication from svn to the user that this is what
she should be doing. "svn info" just does not feel like a tool to
query conflict-type information, since it has historically never
been used for this purpose, and it prints lots of irrelevant
information that I've omitted from the transcript above.
I'd rather type something like 'svn status --human-readable'
with an alias for that which goes 'svn status -h' in order
to get at the human readable conflict description.
Also, we should continue this thread and enhance 'svn status'
to summarise the nature of the tree conflict, so that advanced
users can skip the human readable messages altogether:
http://subversion.tigris.org/servlets/ReadMsg?listName=dev&msgNo=144323
Now, let's try to get rid of this conflict. So the problem is
that the merge tried to copy a file to a location where I've
locally created a file. Let's assume I'm fine with my file
being called something else, and as a first step towards
resolving the conflict, I move my file out of the way:
$ svn mv alpha.copied alpha.copied2
A alpha.copied2
D alpha.copied
$
The tree conflict is still recorded:
$ svn st
M .
! C alpha.copied
A alpha.copied2
$
The commit succeeds nonetheless:
$ svn commit -m "commit anyway"
Sending . <---(mergeinfo)
Adding alpha.copied2
Transmitting file data .
Committed revision 4.
$
Huh... Do we want to allow this?
The conflict is still recorded ...
$ svn st
! C alpha.copied
$
... but the mergeinfo got committed before the conflict was resolved.
OK, so let's try to merge the copy again anyway. I'm a smart user so
I realise the mergeinfo which is now on my top-level branch directory
will prevent me from merging the copy (which my branch does not have yet)
into my branch again:
$ svn mergeinfo --show-revs=eligible ^/trunk
$
So let's first do a record-only reverse-merge (i.e. this is the part
where your typical "I never use branches anyway" user is gonna run away
screaming). We check the log (hey wasn't merging supposed to be
automatic?) and find out that the copy was made in r3, so we run:
$ svn merge --record-only -r3:2 ^/trunk
$ svn diff
Property changes on: .
___________________________________________________________________
Modified: svn:mergeinfo
Reverse-merged /trunk:r3
$
OK, now we can merge the copy again, there's nothing in the way:
$ svn merge ^/trunk
--- Merging r3 through r4 into '.':
A alpha.copied
$ svn status
M .
A + C alpha.copied
$
$ svn resolved alpha.copied
Resolved conflicted state of 'alpha.copied'
$ svn status
M .
A + alpha.copied
So now I have both new files at different paths, which is what I wanted.
I can commit the desired merge result:
$ ls
alpha alpha.copied alpha.copied2 beta epsilon/ gamma
$ svn ci -m "resolved tree conflict on alpha.copied"
Sending .
Adding alpha.copied
Committed revision 5.
=== svn-files-destroy-modified
This is a popular case: Someone on trunk removed a file
that I've modified on the branch:
$ svn status
M .
C alpha
$ svn info alpha
[...]
Tree conflict:
The merge attempted to delete 'alpha'
(possibly as part of a rename operation).
Either you have edited 'alpha' locally, or it has been edited in the
history of the branch you are merging into, but those edits are not
present on the branch you are merging from.
^ The indentation seems off here. (Oh, in fact, it's off in other cases, too.)
First gut reaction: Is my file still there?
$ cat alpha
alpha, but modified
OK, it is. Now, I don't know yet who was trying to remove the file
and why, but I'm going to find out. Actually, I have to go find out
because the file may have been moved somewhere else! So I go browse
the log, and find out the file has indeed been deleted.
After some discussion with other developers we decide to keep the
file in place on the branch. So all I have to do is this:
$ svn resolve --accept=mine-full alpha
Resolved conflicted state of 'alpha'
$ svn status
M .
$
Great, issue settled.
$ svn ci -m "sync branch with trunk"
Sending .
subversion/libsvn_client/commit.c:860: (apr_err=160028)
svn: Commit failed (details follow):
subversion/libsvn_repos/commit.c:124: (apr_err=160028)
svn: Directory '/branch' is out of date
Huh? Why that?
$ svn up
At revision 4.
$ svn ci -m "sync branch with trunk"
Sending .
Committed revision 5.
$
As a user, I don't really grok why the commit failed the first time
around since the update apparently did nothing, but I'm happy to know
that my data made it into the repository the second time. I go home
from work and hope svn won't play such weird tricks on me again tomorrow.
Maybe I'm just seeing things...
As a developer, I'm asking myself whether this is related to us
not updating text-bases in some cases? If so, shouldn't the UI
indicate that this has happened?
=== svn-files-move1-moved
This is an all-time favourite and actually one of the most likely
tree conflict cases. Two teams do refactoring and happen to end
up doing divergent renames of the same file:
$ svn status
M .
A + alpha.moved1
A + alpha.moved2
D C alpha
$ svn info alpha
[...]
Tree conflict:
The merge attempted to delete 'alpha'
(possibly as part of a rename operation).
You have deleted 'alpha' locally.
Maybe you renamed it?
Looking at the logs and status output, I figure out what happened.
I escalate this high-priority problem to the head of department,
who decides to hold a developer meeting instantly in order to settle
the dispute. After much bikeshedding and coffee I finally give up
and we "agree" on the other team's stupid filename, alpha.moved1.
So I diff the files -- renames often go along with internal changes,
but luckily in this case, the files remained the same.
$ svn diff alpha.moved1 alpha.moved2
$ svn rm alpha.moved2
subversion/svn/util.c:864: (apr_err=195006)
svn: Use --force to override this restriction
subversion/libsvn_client/delete.c:65: (apr_err=195006)
svn: 'alpha.moved2' has local modifications
$ svn diff alpha.moved2
$
Huh? I never modified the file locally as far as I know,
but let's try using the force:
$ svn rm --force alpha.moved2
D alpha.moved2
$
OK, seems to have worked. Now let's resolve:
$ svn resolve --accept=working alpha
Resolved conflicted state of 'alpha'
$ svn status
M .
A + alpha.moved1
D alpha
$
That was it!
The above is a bit unrealistic. In real life, renaming files and
file modifications often must go together (e.g. when refactoring
Java classes, or when changing references to things in other
files which were also renamed), so people will want to merge
the files textually.
Let's repeat, and patch the scenario script so that we have textual
modifications in both renamed files:
--- svn-files-move1-moved.sh.orig Fri Nov 14 17:40:19 2008
+++ svn-files-move1-moved.sh Fri Nov 14 17:41:05 2008
@@ -5,10 +5,14 @@
# Move a file in trunk
svn move $trunk/alpha $trunk/alpha.moved1
+# Do a text mod:
+echo "alpha.moved1" > $trunk/alpha.moved1
svn commit -m "moved alpha" $trunk
# Move the same file to a different path in the branch
svn move $branch/alpha $branch/alpha.moved2
+# Do a text mod:
+echo "alpha.moved2" > $branch/alpha.moved2
# Committing here does not affect the merge result
# Merge the rename into the branch
$ svn status
M .
A + alpha.moved1
A + alpha.moved2
D C alpha
$ svn info alpha
[...]
Tree conflict:
The merge attempted to delete 'alpha'
(possibly as part of a rename operation).
You have deleted 'alpha' locally.
Maybe you renamed it?
So this time, the textual modifications add to the problem:
$ diff -u alpha.moved1 alpha.moved2
--- alpha.moved1 Fri Nov 14 17:46:18 2008
+++ alpha.moved2 Fri Nov 14 17:46:18 2008
@@ -1 +1 @@
-alpha.moved1
+alpha.moved2
Now, as a naive user, I try the following trick: I revert the merge,
rename the file to match the name on trunk, re-apply my textual
modifications (they've not yet been committed either as I made them
in the same go as the rename), and merge again. That should give me
a text conflict on the file, right?
We save the local textmods in /tmp/alpha1.diff, conveniently piping
"svn diff" output through sed to fix up the destination path in the diff:
$ svn diff alpha.moved1 alpha.moved2 \
| sed -e 's/^\(+++ alpha.\)moved2/\1moved1/' > /tmp/alpha.moved1.diff
$ cat /tmp/alpha.moved1.diff
Index: alpha.moved2
===================================================================
--- alpha.moved2 (revision 2)
+++ alpha.moved1 (working copy)
@@ -1 +1 @@
-alpha
+alpha.moved2
Now, on to the remaining steps:
$ svn revert -R .
Reverted '.'
Reverted 'alpha.moved1'
Reverted 'alpha.moved2'
Reverted 'alpha'
$ svn status
? alpha.moved1
? alpha.moved2
$ rm alpha.moved[12]
$ svn status
$ svn mv alpha alpha.moved1
A alpha.moved1
D alpha
$ patch -p0 < /tmp/alpha.moved1.diff
Hmm... Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|Index: alpha.moved2
|===================================================================
|--- alpha.moved2 (revision 2)
|+++ alpha.moved1 (working copy)
--------------------------
Patching file alpha.moved1 using Plan A...
Hunk #1 succeeded at 1.
done
$ svn diff
Index: alpha.moved1
===================================================================
--- alpha.moved1 (revision 2)
+++ alpha.moved1 (working copy)
@@ -1 +1 @@
-alpha
+alpha.moved2
Index: alpha
===================================================================
--- alpha (revision 2)
+++ alpha (working copy)
@@ -1 +0,0 @@
-alpha
$ svn merge ^/trunk
--- Merging r2 through r3 into '.':
C alpha.moved1
--- Merging r2 through r3 into 'alpha':
C alpha
Summary of conflicts:
Tree conflicts: 2
Hell's bells, the tree conflicts just multiplied!
$ svn status
M .
? alpha.moved1.orig
A + C alpha.moved1
D C alpha
$ svn info alpha.moved1
[...]
Tree conflict:
The merge attempted to add 'alpha.moved1'.
This action was obstructed by an item in the working copy.
$ svn info alpha
[...]
Tree conflict:
The merge attempted to delete 'alpha'
(possibly as part of a rename operation).
You have deleted 'alpha' locally.
Maybe you renamed it?
So there seems to be no way to make subversion treat the
scenario as a text conflict. Let's try a different route,
make a backup of our file, remove it from version control,
and re-run the merge.
$ svn revert -R .
Reverted '.'
Reverted 'alpha.moved1'
Reverted 'alpha'
$ svn status
? alpha.moved1.orig
$ cat alpha.moved1.orig
alpha
$ rm alpha.moved1.orig
$ ls
alpha.moved1 beta epsilon/ gamma/
$ cat alpha.moved1
alpha.moved2
$ cat /tmp/alpha.moved2.diff
Index: alpha.moved2
===================================================================
--- alpha.moved2 (revision 2)
+++ alpha.moved2 (working copy)
@@ -1 +1 @@
-alpha
+alpha.moved2
$ cp alpha.moved1 alpha.moved1.mine
$ svn rm alpha.moved1
D alpha.moved1
$ svn merge ^/trunk
--- Merging r2 through r4 into 'alpha.moved1':
A alpha.moved1
--- Merging r2 through r4 into '.':
C alpha
Summary of conflicts:
Tree conflicts: 1
$ ls
alpha.moved1 alpha.moved1.mine beta epsilon/ gamma/
Now we manually merge alpha.moved1 and alpha.moved1.mine, which for
sake of argument, results in:
$ cat alpha.moved1
alpha.moved1
alpha.moved2
We're now left with a single tree conflict on alpha,
which we can safely mark as resolved:
$ rm alpha.moved1.mine
$ ls
alpha.moved1 beta epsilon/ gamma/
$ svn status
M .
! C alpha
R + alpha.moved1
$ svn resolved alpha
Resolved conflicted state of 'alpha'
$ svn status
M .
R + alpha.moved1
The alpha.moved1 on the branch has now been replaced with
its counterpart on trunk, and it includes local changes
made to it on the branch.
Before we can commit, the spurious out-of-date problem
comes up again:
$ svn commit -m "synced branch with trunk"
Sending .
subversion/libsvn_client/commit.c:860: (apr_err=160028)
svn: Commit failed (details follow):
subversion/libsvn_repos/commit.c:124: (apr_err=160028)
svn: Directory '/branch' is out of date
$ svn update
At revision 4.
$ svn commit -m "synced branch with trunk"
Sending .
Replacing alpha.moved1
Transmitting file data .
Committed revision 5.
That's it for now. I might look into more cases another time.
It seems like handling tree conflicts is not going to be easy for users.
In any case, resolving these conflicts requires quite a bit of patience
and skill from the user. Given the complexity of the problem, this does
not surprise me. I hope, however, that we can make further improvements
to the UI to make the resolution process a bit more straightforward,
if possible.
Comments, ideas?
Thanks,
Stefan
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org