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

Re: Yet more problems with tree conflicts

From: Stefan Sperling <stsp_at_elego.de>
Date: Tue, 23 Jun 2009 14:16:12 +0100

On Mon, Jun 22, 2009 at 06:59:40PM -0400, Sean E. Russell wrote:
> Sorry for the multipart HTML; there's formatting in here I'd like to
> preserve.

I use mutt, so the formatting was probably lost anyway ;)

> I'm getting false conflicts on merging a branch back into the branch
> from which it was branched

One thing to always keep in mind about tree conflict detection
in Subversion:

        Yes, there are false positives!

This is bad, but compromises had to be made in certain situations
because of limitations in Subversion's current design.
We chose to err on the safe side of things, which sometimes causes
conflicts to be flagged even though there are none.
We hope to improve the situation in future releases (1.7, 1.8 and so on).

> SVN 1.6.3 on both the client and the server.
> dx325002tp% svn log -v --stop-on-copy
> http://nightrider/repos/scout/branches/R12-PRFix/scout/src/com/trueposition/scout/client/wlsconfigclient/GuiCarrierCellsiteSectorAntennaEditors.java
> | grep GuiCarrierCellsiteSectorAntennaEditors.java
> A
> /branches/R12-PRFix/scout/src/com/trueposition/scout/client/wlsconfigclient/GuiCarrierCellsiteSectorAntennaEditors.java
> (from
> /branches/R28.0-BRANCH/scout/src/com/trueposition/scout/client/wlsconfigclient/GuiCarrierCellsiteSectorAntennaEditors.java:10253)
> Note that there's only a single version of that file on the the target
> branch; also, note where it came from.
> Now, I check out /branches/R28.0-BRANCH, and try to merge from R12-PRFix
> back into that branch. I can't reintegrate, because we occasionally
> merge individual changes between branches, which confuses --reintegrate.

This can cause some problems with merge tracking unless you are
really careful. I know this is necessary in many environments
and Subversion should be made to handle this much better, but
at the moment you should try sticking to the "release branch"
and "feature branch" use cases if possible. That's what the
current merge-tracking implementation can handle really well.

See also
and other files in

> ...
> $ svn co http://nightrider/repos/scout/branches/R28.0-BRANCH
> $ cd R28.0-BRANCH
> $ svn log -v -r 9615 http://nightrider/repos/scout/branches/R12-PRFix
> ------------------------------------------------------------------------
> r9615 | skumar | 2009-03-06 17:54:19 -0500 (Fri, 06 Mar 2009) | 3 lines
> Changed paths:
> A /branches/R12-PRFix (from /branches/R28.0-BRANCH:9614)
> Branch for Legacy PR's fixes in R12. (see
> http://tpwiki/index.php/12.0_Branches#R12-PRFix)
> $ svn merge -r 9614:HEAD http://nightrider/repos/scout/branches/R12-PRFix
> ...
> C
> scout/src/com/trueposition/scout/client/wlsconfigclient/GuiCarrierCellsiteSectorAntennaEditors.java
> C
> scout/src/com/trueposition/scout/client/wlsconfigclient/GuiMechanicalSurveyEditors.java
> Conflict discovered in
> 'scout/src/com/trueposition/scout/client/wlsconfigclient/WlsConfigTreeCellRenderer.java'.
> Select: (p) postpone, (df) diff-full, (e) edit,
> (mc) mine-conflict, (tc) theirs-conflict,
> (s) show all options: ^Csvn: Caught signal
> svn: Error reading spooled REPORT request response
> dx325002tp% svn stat
> scout/src/com/trueposition/scout/client/wlsconfigclient/GuiCarrierCellsiteSectorAntennaEditors.java
> C
> scout/src/com/trueposition/scout/client/wlsconfigclient/GuiCarrierCellsiteSectorAntennaEditors.java
> > local obstruction, incoming add upon merge
> The file was created in branch A, merged to branch B, and then branch B
> was merged back into branch A. And SVN claims that there's a tree
> conflict on the file which wasn't ever changed in branch B.

This is caused by yet another problem in Subversion's design :)
When you merge a file to a branch, Subversion does a copy like this:

 copy ^/trunk/file ^/branches/branch/file (where ^ is the repo URL)

When merging the 'add', Subversion does the reverse:

 copy ^/branches/branch/file ^/trunk/file

The copy then is an "add with history". I.e. a file is added at a
path in rX, with a backpointer telling which path at rY it came from.

So all the tree conflict detection code ends up seeing in the target
working copy when you do the merge is an add on top of a file that's
already present.
It will flag a conflict, because it is *possible* that conflicting
files have been added at the same path on the branch and trunk.

That's not optimal and will be improved in the future, but
right now you'll have to live with this behaviour :(

Note that if you just changed a file which existed at the time
you branched, when reintegrating the branch you will get a textdelta
instead of an 'add' so the tree conflict detection logic won't trigger.

> Specifically, these files were *not* created on any other branch but A,
> so it shouldn't be possible to get conflicts on them. Notice that the
> file didn't change on either branch after it was merged to B:

You are right that in your case, Subversion should really be
doing something different (it should realise the files are
the same or somehow related and merge them textually).

Since you already know there's no conflict, so just tell Subversion so:

 svn resolved scout/src/com/trueposition/scout/client/wlsconfigclient/GuiCarrierCellsiteSectorAntennaEditors.java

Make sure that file really contains what you want it to contain and
you're done.

Sorry about this extra step, but it's not avoidable right now.
If you want to help to improving this, you are very much welcome to,
we could very much use more helping hands :)

> Additionally, although possibly unrelated, SVN isn't merging files
> correctly. SVN says that files have been merged, but when diffing the
> resulting files, the changes from the other branch aren't always brought
> in. Consider:
> $ svn annotate
> http://nightrider/repos/scout/branches/R28.0-BRANCH/scout/src/com/trueposition/scout/client/mapcomponent/LVPortPopup.java
> ...
> 10251 apavlin
> if(!cgi.internalDasGroupId.isNull && cgi.internalDasGroupId.value > 0){
> 10251 apavlin label = new JLabel(" DAS
> Group ID="+ cgi.internalDasGroupId.value, JLabel.LEFT);
> 10251 apavlin label.addMouseListener(this);
> 10251 apavlin }
> 10251 apavlin contentPane.add(label);
> ...
> The lines were changed in version 10251; they were removed in the
> R12-PRFix branch in 10271 (annotate isn't helpful in this case). The
> "rebase" of the PRFix branch occurred in 10265, so the removal of these
> lines occurred* after* the rebase. However, after the merge (where SVN
> auto-merged this file with no conflicts), the lines are still present:
> diff -r --exclude .svn
> R28.0-BRANCH/scout/src/com/trueposition/scout/client/mapcomponent/LVPortPopup.java
> R12-PRFix/scout/src/com/trueposition/scout/client/mapcomponent/LVPortPopup.java
> 115,119d114
> < if(!cgi.internalDasGroupId.isNull &&
> cgi.internalDasGroupId.value > 0){
> < label = new JLabel(" DAS Group ID="+
> cgi.internalDasGroupId.value, JLabel.LEFT);
> < label.addMouseListener(this);
> < }
> < contentPane.add(label);
> However, other changes in this file were correctly merged.

This is probably a bug.
It would be nice to have a small script that demonstrates this
problem. The script should start out with creating an empty
repository and do just enough Subversion command-line foo
to show this problem.

> One of three things is going on:
> * We're using SVN incorrectly. It is possible; all merges are being
> done from the command line, and we could have messed something
> up. If so, we're doing it consistently, because encounter these
> issues across several developers, across several branches. It
> almost always is a merge back down to the parent branch.
> * Our repository is broken, or the metadata is. Again, this is
> possible, but I have no way of checking this. The repository
> looks clean from svnadmin's POV, and we don't have any other
> problems with check-in, check-out. It is just merging giving us
> grief.
> * Subversion's merging and merge tracking is broken.
> If it is the last, I'll file a PR, but I suspect that it is too late for
> us; these sorts of issues really scare our QA department.

I'd say it's a combination of all these factors.

Yes, Subversion has problems. It's not perfect. This is because
many of the problems it is trying to handle are not trivial (merging
arbitrary subsets of a revision of a tree with arbitrary subsets of
other revisions of the tree), and because it started out as just a
better CVS and is gradually starting to grow out of these baby shoes.

And now people already start using it as if it was the second coming
of ClearCase even though it is not [yet]. Many problems exist because
the original design did not account for difficult requirements which
people now expect Subversion to handle when they hear that "it supports
merge tracking and tree conflict detection". Well...
E.g. tree conflict handling could be much better with a tweaked
design, but it's a lot of work, and users also expect things
to be backwards compatibile virtually forever.

Users should know about these limitations and how to work with them.
Posting about problems here, like you just did, is a good step in
this direction. Subversion can be a very helpful tool, but as with
any other tool (CVS, C, Linux, Windows, Bicycles, ...) you have to
know how to work with its limitations in order to use it well.

Understanding the articles on merging I linked to above
really goes a long way in helping you avoid many problems.

Received on 2009-06-23 15:16:43 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.