I think I've changed my mind re: SVK and svn:externals, because it turns out
this works just like you'd hope it would1:
svk mirror svn://project1/ //mirror/project1 svk mirror svn://project2/ //mirror/project2 svk sync --all svk cp //mirror/project1 //local/project1 svk cp //mirror/project2 //local/project1/vendor/project2 svk push //local/project1
Then later do:
svk pull //local/project1/vendor/project2 svk push //local/project1
I've decided that svn:externals is the real hack. I've generally seen it used
to solve two different problems: (a) exporting common modules as part of
different projects stored in the same repository; and (b) importing "vendor
branches" from other repositories. The problem is that it doesn't really do
either well.
First, svn:externals requires a fully-qualified URI. This causes it to break
if either the repository moves or the repository is accessed by different
protocols. Both of those problems can be "solved" with "don't do that," but
I've personally had cause for both. Obviously either of these will break
people vendoring from your repo, but a URI-change shouldn't break internal
module sharing. The fact of the matter is that the URI for a repo is a
non-canonical name — and Subversion even accounts for this fact by generating
a UUID for each repository.
Second, directly incorporating some chunk of repo into your project is rarely
what you want to do. I've been guilty of this before — and am rather
embarrassed thinking about it. I might be going out on a limb, but I think
most vendor branches need to (a) be pinned to a known-stable version; and (b)
include local modifications. For the former, svn:externals depends on either
good tagging in the source project or (shiver) pinning to a specific revision.
For the latter, svn:externals provides no help whatsoever. In fact, the
Subversion manual chapter on vendor branches barely mentions svn:externals,
preferring instead careful branch-management and merge practices2.
So I think SVK's way of doing things is quite a bit closer to a solution, although still not quite. It solves the problems discussed above, but still requires the local mirror exist (i.e., external configuration), and breaks when switching the actual source (tag, etc.) of the vendor branch3. "Here's 2 cents — go get yourself a real distributed version control system," I hear some of you saying...
1 For the SVK-unfamiliar, this is almost exactly what Piston lets you do, only in both directions.
2 And a Perl script, apparently.
3 Breaks pull and the UUID-tracking, that is. A generic smerge will still
work just fine.
Commentary most sage