Merging from Foreign Repositories

This article is mirrored with permission from the original location Inactive links have been removed or updated.

Author: C. Michael Pilato

Posted: 2008-03-29

For many folks, the forthcoming Subversion 1.5 release gets billed as something like "merge tracking and some other stuff". It’s probably true that the work put into the new merge tracking feature outweighs the investments in other individual areas. But of course, Subversion 1.5 isn’t about merge tracking alone. There are several other major features coming in this release. And as you’d expect, the Subversion community has made countless bugfixes over the past year-and-a-half, too. But today I want to briefly talk about one half-bugfix, half-feature, that might have slipped in under your radar: merges from foreign repositories.

Subversion has for some time now allowed you — kinda, sorta — to perform merge operations where the sources of the merge live in one repository but the target working copy (the thing you are merging to) comes from a different ("foreign") repository. After all, since Subversion models merges as essentially the application of a diff, you might expect that the source of those diffs wouldn’t matter all that much. But this is a feature that nobody really talks about: the Subversion public API doesn’t mention it; the Subversion book doesn’t mention it; Subversion’s release notes don’t brag about it. In fact, the only reason I even knew the feature existed was because of code comments I came across while hacking on Subversion’s merge tracking feature. Why the shroud of secrecy? Well, it might be one of those accidental features — the ones that weren’t specifically intended to work, but mostly did anyway. Or perhaps the reason is that it only worked sometimes. At any rate, merges from foreign repositories is practically a hidden feature.

Apparently empowered by the spirit of "by golly this ought to work", one openCollabNet community member found this feature, though and found its shortcomings. User "argeman" posted the following to the merge-tracking beta program forums:

i have tested the svn 1.5 alpha2 a bit (converted some repositories and played around with those). it works completely great until now. The only thing that is still not working (it never worked in previous subversion-releases): If i try to merge changes from a different repository, that will not work for added files.

I’d never really played with merges from foreign repositories myself, but immediately recognized the value of the feature. I can summarize it in two words: "vendor branches". Vendor branches are a common way of maintaining private customizations to somebody else’s code without mirroring that code change-for-change. There are different ways to make this work. For example, you might use individual branches which are pure mirrors of a given vendor’s release package contents, and then another branch which contains the currently employed version of the vendor package plus your private modifications. Your upgrade your customized package by applying the diffs between pure vendor releases to your customized copy. Alternatively, you might keep in a version control branch only the customized copy of the vendor package, and use diffs generated as patches between unversioned vendor package contents to upgrade that branch. And some masochists avoid the powers of version control altogether and simply maintain custom patch files which need to be updated with each new release of the vendor’s package. (If you’re one of those, there are people who can help you deal with your illness.)

The ability to merge from foreign Subversion repositories, then, provides a sort of hybrid approach similar to the first and second methods I previously mentioned. In this approach, you need to maintain only that single customized copy of the vendor’s package instead of also tracking pure mirrors of the vendor’s release (because the pure versions can be readily obtained from the vendor’s Subversion repository). But now you get to use version control tools to merge the differences between those pure versions into your customized copy, instead of dealing with messy patch files.

Unfortunately, "argeman" wasn’t posting to say, "Hey, I just found this feature and it works great!" The post was to tell us that the feature had potential, but failed to handle files which needed to be added as a result of the merge. Here, however, is the joy of working on open source software. It took me all of 40 minutes to change Subversion’s code to fix the problem and compose a regression test, plus some additional time thereafter doing some related follow-up fixes. So when Subversion 1.5 ships, I expect merges from foreign repositories to be supported at the same basic level that intra-repository merges are. Renames in the merge source will still cause the same complications that they always have in Subversion, and the merge tracking logic will be bypassed when merging from foreign repositories, but the merge should complete successfully in the commonmost situations.

About the author

C. Michael Pilato is a core Subversion developer, co-author of Version Control With Subversion (O'Reilly Media), and the primary maintainer of ViewVC. He works remotely from his home state of North Carolina as a software engineer for CollabNet, and has been an active open source developer since early 2001. Mike is a proud husband and father who loves traveling, soccer, spending quality time with his family, and any combination of those things. He also enjoys composing and performing music, and harbors not-so-secret fantasies of rock stardom. Mike has a degree in computer science and mathematics from the University of North Carolina at Charlotte.