Though I’ve used SVN on-and-off over a number of years, I admit that I don’t know all about it. Recently I had a few issues using SVN with respect to merging changes between branches that weren’t immediately obvious. Why? SVN MergeInfo.
Seemingly I was not able to merge changes from one branch to another, despite:
Like all situations where you get stuck, I had a bit of a Google and accompanying read of the links that I found. There were a lot of unhelpful links, but then I found an article by Chris Oldwood.
This really put me in the right direction – thanks Chris! He discussed the way in which Subversion manages merges, specifically in contrast to other version control systems such as ClearCase. It was then that I came to learn about an advanced feature of SVN I’d not heard of before: mergeinfo. In his post about SVN mergeinfo, he states:
Subversion uses a special property on files and folders to record when a merge has taken place called “svn:mergeinfo”. The value of the property is a list of the branches (and associated range of revisions) that have been merged to date – irrespective of whether a physical change has been made to the item itself, e.g.
So after reading this article and scanning the relevant section of the SVN Redbook, I then understood why the merges seemingly had no affect. I had performed the merge previously and so when I attempted to run the branch merge again SVN skipped over the file having determined the merge had already occurred. Sorry for the slight tongue-twister there.
So after finding out this, I reviewed one of the files in question by using the propget option for SVN. Have a look in the example below.
svn propget svn:mergeinfo . /trunk:341-349,355
You can see from this output that revisions 341-349 and 355 are no longer eligible to be merged as they’re already recorded as having occurred. So SVN saw this and skipped over it. Hey, why would you want to do it twice and give yourself a merge conflict.
But in this caase, I wanted do the merge again? Gladly for me, there is a way around it. After learning about SVN’s notion of history and ancestry, when it comes to merging, I found that I could run the merge command again, but pass the –ignore-ancestry option to it. For example:
svn merge --ignore-ancestry -r1234:1235 <your/svn/repo/branch> \ <your/working/copy/path>
This told SVN to ignore the mergeinfo information and operate as though this were the first time. Please be aware that the SVN redbook does warn against this as you may end up with one, or a series, of file conflicts; which are usually never anyones idea of fun to have to resolve. So consider yourself warned.
I hope that this has helped shed light on this for you if you’ve encountered it and wondered what the hell is going on. Have you had previous experience with this? Please share your battlefield tales with us. Whilst not the best version control system, SVN is still quite a reliable and feature-rich tool. I hope this helps you when using it.
If you liked what you read and would like to see more, please retweet it, or give it a like on Facebook or even give it some Digg love. And we always value you feedback and comments.