svn externals ... yes or no?

1.1k views Asked by At

I've read a few answers on here that condemn the use of svn:externals. I do see how they can be misused, and it does make us more dependent on Subversion, but I really don't see our group moving away from it anytime soon.

Anyway, here's my dilemma. We have Solutions that reference multiple Projects which are in their own section of the repository. Many of these Projects are shared between multiple Solutions, and we also don't want to preclude the sharing of our Projects. We also have several fixed version dependencies checked into our repository (unit test frameworks, libraries, etc.).

I would like to configure several 'workspaces' that use ONLY externals (as far as Subversion is concerned they would just be empty directories, or contain maybe a single solution file) to configure Solutions for our developers. Checking out most Projects on their own won't be enough to build them, but checking out its workspace will be enough to build it because all its dependencies will come with it. Has anyone else implemented a similar solution, and would svn:externals be a good way to go about this? What words of caution do you have for me if we go down this road?

Basically the structure would look like this (trunk/branches/tags omitted for brevity):

/projects
   /project1
   /project2
/dependencies
   /xUnit
      /1.5
      /1.4
   /NHibernate
      /2.1.0
      /2.0.1
/workspaces
   /project1
      /project1 (external to ^/projects/project1)
      /xUnit (external to ^/dependencies/xUnit/1.5)
      /NHibernate (external to ^/dependencies/NHibernate/2.0.1)
   /project2
      /project2 (external to ^/projects/project2)
      /xUnit (external to ^/dependencies/xUnit/1.4)
      /NHibernate (external to ^/dependencies/NHibernate/2.1.0)
3

There are 3 answers

1
cletus On BEST ANSWER

SVN Externals are Evil; Use Piston or Braid seems typical of the anti-external camp. And the poster does have a point.

I think a better criteria is:

  • Use external references for internal projects that you can change; and
  • Use vendor branches for external repositories you have no control over.

So it seems the problems with svn externals come from people use them as a substitute for vendor branches. I've seen several people complaining about them in the context of third-party Rails plugins.

So in your case, assuming these projects are all "internal", then I think an svn external is a perfectly valid approach.

0
Vladimir On

If your svn:externals only reference 3rd party libraries, why not simply use a Maven/Ivy repository? These are for the Java world and I don't know their .Net pendents but I'm quite sure they exist.

I only use svn:externals to share Ant antlib files, until they give the possibility to load them from a jar archive.

0
Barak C On

I definitely agree with the previous answer. From my experience using externals is excellent solution for infrastructure modules and "internal" libraries as long as you set the externals to specific tag of the library and not to its trunk.

I didn't understand exactly why you want to use workspace that is entirely based on externals and not adding the externals directly to the project itself. My approach is that any project you create on the SVN must be "built-able" when it been checked out.

In my approach your repository should looks like this:

/dependencies
     /xUnit
           /tags
                /1.5
                /1.6
           /trunk
     /NHibernate
           /tags
                /2.1.0
                /2.0.1
           /trunk
/projects
     /project1
           /tags
                /1.0
                    /sources
                    /xUnit(externals to /dependencies/xUnit/tags/1.5)
                    /NHibernate(externals to /dependencies/NHibernate/tags/2.0.1)
           /trunk
                /sources
                /xUnit(externals to /dependencies/xUnit/tags/1.6)
                /NHibernate(externals to /dependencies/NHibernate/tags/2.0.1)
     /project2
           /tags
                /1.0
                    /sources
                    /xUnit(externals to /dependencies/xUnit/tags/1.6)
                    /NHibernate(externals to /dependencies/NHibernate/tags/2.0.1)
           /trunk
                /sources
                /xUnit(externals to /dependencies/xUnit/tags/1.6)
                /NHibernate(externals to /dependencies/NHibernate/tags/2.1.0)