[svn] Why am I getting tree conflicts in Subversion?

I had a feature branch of my trunk and was merging changes from my trunk into my branch periodically and everything was working fine. Today I went to merge the branch back down into the trunk and any of the files that were added to my trunk after the creation of my branch were flagged as a "tree conflict". Is there a way to avoid this in the future?

I don't think these are being properly flagged.

This question is related to svn merge tree-conflict

The answer is


I had a similar problem. The only thing that actually worked for me was to delete the conflicted subdirectories with:

svn delete --force ./SUB_DIR_NAME

Then copy them again from another root directory in the working copy that has them with:

svn copy ROOT_DIR_NAME/SUB_DIR_NAME

Then do

svn cleanup

and

svn add *

You might get warnings with the last one, but just ignore them and finally

svn ci .

A scenario which I sometimes run into:

Assume you have a trunk, from which you created a release branch. After some changes on trunk (in particular creating "some-dir" directory), you create a feature/fix branch which you want later merge into release branch as well (because changes were small enough and the feature/fix is important for release).

trunk -- ... -- create "some-dir" -- ...
     \                                  \-feature/fix branch
      \- release branch

If you then try to merge the feature/fix branch directly into the release branch you will get a tree conflict (even though the directory did not even exist in feature/fix branch):

svn status
!     C some-dir
      >   local missing or deleted or moved away, incoming file edit upon merge

So you need to explicitly merge the commits which were done on trunk before creating feature/fix branch which created the "some-dir" directory before merging the feature/fix branch.

I often forget that as that is not necessary in git.


This can be caused by not using the same version clients all over.

Using a version 1.5 client and a version 1.6 client towards the same repository can create this kind of problem. (I was just bitten myself.)


If you encounter tree conflicts which do not make sense because you didn't edit/delete/come anywhere near the file, there is also a good chance that there was an error in the merge command.

What can happen is that you previously already merged a bunch of the changes you are including in your current merge. For instance, in trunk someone edited a file, and then later renames it. If in your first merge you include the edit, and then in a second merge include both the edit and the rename (essentially a remove), it will also give you a tree conflict. The reason for this is that the previously merged edit then appears as your own, and thus the remove will not be performed automatically.

This can occur on 1.4 repositories at least, I'm not sure whether the mergetracking introduced in 1.5 helps here.


Subversion 1.6 added Tree Conflicts to cover conflicts at the directory level. A good example would be when you locally delete a file then an update tries to bring a text change down on that file. Another is when you you have a subversion Rename of a file you are editing since that is an Add/Delete action.

CollabNet's Subversion Blog has a great article on Tree Conflicts.


I had this same problem, and resolved it by re-doing the merge using these instructions. Basically, it uses SVN's "2-URL merge" to update trunk to the current state of your branch, without bothering so much about history and tree conflicts. Saved me from manually fixing 114 tree conflicts.

I'm not sure if it preserves history as well as one would like, but it was worth it in my case.


In my experience, SVN creates a tree conflict WHENEVER I delete a folder. There appears to be no reason.

I'm the only one working on my code -> delete a directory -> commit -> conflict!

I can't wait to switch to Git.

I should clarify - I use Subclipse. That's probably the problem! Again, I can't wait to switch...


What's happening here is the following: You create a new file on your trunk, then you merge it into your branch. In the merge commit this file will be created in your branch also.

When you merge your branch back into the trunk, SVN tries to do the same again: It sees that a file was created in your branch, and tries to create it in your trunk in the merge commit, but it already exists! This creates a tree conflict.

The way to avoid this, is to do a special merge, a reintegration. You can achieve this with the --reintegrate switch.

You can read about this in the documentation: http://svnbook.red-bean.com/en/1.7/svn.branchmerge.basicmerging.html#svn.branchemerge.basicmerging.reintegrate

When merging your branch back to the trunk, however, the underlying mathematics are quite different. Your feature branch is now a mishmash of both duplicated trunk changes and private branch changes, so there's no simple contiguous range of revisions to copy over. By specifying the --reintegrate option, you're asking Subversion to carefully replicate only those changes unique to your branch. (And in fact, it does this by comparing the latest trunk tree with the latest branch tree: the resulting difference is exactly your branch changes!)

After reintegrating a branch it is highly advisable to remove it, otherwise you will keep getting treeconflicts whenever you merge in the other direction: from the trunk to your branch. (For exactly the same reason as described before.)

There is a way around this too, but I never tried it. You can read it in this post: Subversion branch reintegration in v1.6


I don't know if this is happening to you, but sometimes I choose the wrong directory to merge and I get this error even though all the files appear completely fine.

Example:

Merge /svn/Project/branches/some-branch/Sources to /svn/Project/trunk ---> Tree conflict

Merge /svn/Project/branches/some-branch to /svn/Project/trunk ---> OK

This might be a stupid mistake, but it's not always obvious because you think it's something more complicated.


Until today, for since at least 3 months ago, I regularly encountered hundreds of tree conflicts when attempting to merge a branch back into the trunk (using TortoiseSVN 1.11). Whether rebased or not, BTW. I've been using TortoiseSVN since its v1, back in 2004, and I used to reintegrate branches all the time. Something must have happened recently I suppose?

So today I ran this simple experiment, and I found what was creating these crazy conflicts:

  1. I forked off the trunk @393;
  2. I modified tens of files randomly, as well as creating new ones;
  3. I committed. Now @395 (a colleague forked off at 394 to perform his own stuff).
  4. Then I tried to reintegrate the branch back into the trunk, test only; following TortoiseSVN's recommendation in the wizard: "to merge all revisions (reintegrate), leave that box empty". To achieve this, I right-clicked onto the trunk folder, and chose "TortoiseSVN > Merge, from /path/to/branch", and I left the rev range empty, as advised on the dialog.

Discussion: (see attachment)

all revisions... of what? Little did I know that the client must have been referring to "all revisions of the target! (trunk)", as, in the process of reintegrating that branch, I saw the mention "Merging revisions 1-HEAD"! OMG. Poor Devil, you're falling to your death here. That branch was born @393, can't you read its birth certificate, for God's sake? this is why so many conflicts occurred: SVN-cli is going on a foolish spree from revision 1

Resolution:

  1. Contrarily to what's advised by the wiz, do specify a range, that covers ALL revisions of...the branch's life! therefore, 394-HEAD;
  2. now run that merge test again, and get a cigar. (see second attachment).

Moral: I can't comprehend why they still haven't fixed that bug, because it is one, I'm sorry. I should take the time to report this with them.


I came across this problem today as well, though my particular issue probably isn't related to yours. After inspecting the list of files, I realized what I had done -- I had temporarily been using a file in one assembly from another assembly. I have made lots of changes to it and didn't want to orphan the SVN history, so in my branch I had moved the file over from the other assembly's folder. This isn't tracked by SVN, so it just looks like the file is deleted and then re-added. This ends up causing a tree conflict.

I resolved the problem by moving the file back, committing, and then merging my branch. Then I moved the file back afterward. :) That seemed to do the trick.