Thursday, September 24, 2009

Subversion merge after refactor

I recently discovered the popular Subversion VCS has a problem to apply differences to moved files. Unfortunately I discovered this after a big and time consuming refactor process so I had to find out an "easy-to-apply" solution to this problem.


Image via Wikipedia


My repository layout is something like:


project
+-- trunk
+-- branches
+-- refactoring


The target operation is to merge the refactoring branch onto the trunk, but to avoid blocking all other people I decide to perform the inverse: apply all updates on the trunk to the refactoring branch. On merge completion I'm going to switch the twos.

First of all I started merging the trunk onto the branch ignoring all the "Skipped missing target" messages which whould occur for each file you moved/renamed: in my case this was happening for 99% percent of the files, as it was a massive refactor, and only downloading added files (which you may still need to review).

svn merge -r 3855:HEAD http://svn.smartlab.net/project/trunk


Then I moved on the trunk working copy and performed a huge diff starting from the revision in which I created the branch and stopping to the HEAD revision:


svn diff -r 3855:HEAD . > rev.3855-HEAD.diff

Next step was to open the diff file both in eclipse (right click on the checkout folder, Team/Apply patch...) and within a text editor (I used gedit, but vi or notepad++ should get you to the same results): I used eclipse to easily find unmatched entries (shown with a red cross) and applied a textual search & replace on the diff file in the text editor.

At the end of my process I had a diff file I could use to patch my branch to have it up to date against the trunk, with a few missing/unappliable patches against those files I had removed definitely from my branch.

The process was easy, but needed time and the results depends on the accuracy you perform it. But at least all my work has not been void!

BTW: if you are not mass refactorying you can use the Eclipse support to select an unmatched diff entry and move it to another file, this can be really usefull if you have moved only a few files.


No comments: