Question

I'm trying to merge a trunk to a branch, but ending up with a lot of tree conflicts, leaving no files merged. To resolve the conflicts, I'm just opening the file and copying contents by hand which just defeats the purpose of a merge operation. What is the right way to merge a trunk to a branch (in subclipse) ?

Was it helpful?

Solution

How was that branch created? Was it created by using svn cp, or were those files manually copied into that branch?

Let's look at the following:

$ svn mkdir trunk
$ vi trunk/foo trunk/bar
$ svn add trunk/foo trunk/bar
$ svn commit -m"Added foo and bar to trunk"

You now have two files on trunk.

$ svn mkdir --parents branches/1.0
$ cp trunk/* branches/1.0/
$ svn add branches/1.0/*
$ svn commit -m"Duplicated files onto branch"

What I have done is create two entirely different foo and bar on the 1.0 branch. These two files, according to Subversion have absolutely nothing to do with each other. If you make a change on the 1.0 branch, and attempt to merge these changes back to trunk, you will get a lot of conflicts with messages like "local add, incoming add".

What the above user should have done is this:

$ svn cp --parents trunk branches/1.0
$ svn commit -m"Branched trunk and not merely duplicate files"

Now, there's a relationship that Subversion understands between the files on trunk and on the 1.0 branch. Merging will go smoothly.

Here's another way to break a merge:

$ svn delete trunk/foo
$ svn commit -"deleted foo"
$ svn cat -rPREV trunk/foo@PREV > foo
$ svn add foo
$ svn commit -m"Added foo back in. Shouldn't have deleted it.

According to Subversion, there are now two completely different files named foo in the trunk. There's the file you deleted, and there's the file you added. These two files have nothing to do with each other. Imagine if I branched (the correct way using svn cp) to the 1.0 branch, then did my delete and copy of foo. The merge of the 1.0 branch back to trunk will have a conflict because the foo on the branch has no relationship with the foo on trunk.

To restore a file, you need to copy the revision that was deleted (or use svn merge -c).

$ svn cp -rPREV http://svn.repo/svn/trunk/foo@PREV .
$ svn commit -m"Actually old foo now has been restored! Merges will work"

If you branched incorrectly, or deleted and re-added files back to trunk, you will get conflicts. You can try using the --ignore-ancestory parameter, and you can use --dry-run to test your merge before running the actual merge.

If you manually merge, you can use svn merge --record-only to just record the fact you did a merge without actually doing one. This might help the next time you do a merge since you're at least recoding what you've manually done.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top