[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: file externals & URLs

From: David Weintraub <qazwart_at_gmail.com>
Date: Tue, 23 Nov 2010 09:09:56 -0500

On Tue, Nov 23, 2010 at 8:43 AM, Bastien Semene
<bsemene_at_cyanide-studio.com> wrote:
> Hi,
>
> I read in the svn-book that file externals are supported only in the same
> repository. But it is not clear in my repositories architecture :
>
> My repositories are accessed through Apache and all use the same FQDN/vhost.

So, you have multiple repositories on the same host?

No, each repository has its own database and is distinct even though
they maybe on the same host and even in the same Apache instant.

However, I've usually find that externals aren't really worth the
effort it takes to really support them.

Let's say you have a project "foo" which is
http://FQDN/repo1/foo/trunk, and it is using as an external project
http://FSND/repo1/bar/trunk. So, you create the following external:

    $ svn propset svn:externals http://FQDN/repo1/bar/trunk bar

Everything is fine, and you're ready to do a release of foo:

    $ svn cp http://FQND/repo1/foo/trunk http://FQND/repo1/foo/tags/FOO-1.0

However, all is not well. Your tag is not static because whenever
http://FQND/repo1/bar/trunk changes, the files you'd checkout under
FOO-1.0 will change. That's because your svn:externals property points
to the trunk of bar, and not to a particular revision. If you need to
create a new release FOO-1.0.1 based upon FOO-.1.0, the files under
bar would not be what you think they are.

In order to get around this, you need to point your svn:externals
property in foo to a particular revision of bar. This could be a
tagged revision (although in theory tags can change, but not likely).
Or to an actual revision of bar (using the -r parameter). Also, you
may want to peg bar to that revision while you're at it. Otherwise,
the directory structure of bar could change, and that would affect
your tag of foo. Thus, when you create the external, you really should
do something like this:

    $ svn propset svn:externals -r1000 ^/repo1/bar/trunk_at_1000 bar

This will freeze your svn:externals project at revision 1000 of your
repository, and make sure that the way the bar directory looks the
same as it did at revision 1000.

Another thing I've seen is from sites where the trunk, branches, and
tags directories are all on the root of the repository. Thus the URL
for FOO would be:

     http://FQDN/repo1/trunk/foo
     http://FQDN/repo1/tags/foo/FOO-1.0

and the URL for BAR would be:

     http://FQDN/repo1/trunk/bar
     http://FQDN/repo1/tags/bar/FOO-1.0

In this case, you could set the svn:externals like this:

    $ svn propset svn:externals ../../bar bar

This way, the branching and tagging schemes of BAR and FOO will match
even when you do a URL copy and create new branches and tags (as long
as both FOO and BAR have the same branches and tags setup).

I find the best way is to just make BAR a releasable subproject. You
could zip up its source code or compile bar into some sort of object
file that FOO can use (a jarfile for a Java project, or a *.dll or
*.so for C or C++ projects). Then, I'd have my build file copy the
correct version of bar down from the release repository as part of my
build process. That way, you don't have to maintain svn:externals, or
be limited by the fact that svn:externals projects have to live in the
same repository as the master project.

The svn:externals seemed like such a good idea when I first heard of
Subversion, but I quickly discovered that it can be very difficult to
implement correctly.

-- 
David Weintraub
qazwart_at_gmail.com
Received on 2010-11-23 15:10:34 CET

This is an archived mail posted to the Subversion Users mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.