Reputation: 63738
We've currently got a single repo with codesion, http://John.svn.cvsdude.com, with a single SVN project http://John.svn.cvsdude.com/MyProject, which contains a few subdirs for individual Visual C++ solutions
This all started as one application and though we did split off separate library projects for future re-use, it's still all the same SVN project. Lets say we aim to have multiple applications with some overlap in libraries used, what's the right/best way to set this up in SVN? Of course one could just keep one SVN project and put app-projects and library-projects as sub-dirs, but it hardly seems right somehow.
Say we have App1, App2, App3 and LibraryA, LibraryB, LibraryC, LibraryD where these are all separate projects/solutions... how would you organise this under one (or more repos)? Is there a best-practice?
Upvotes: 1
Views: 366
Reputation: 1437
this is Jack from CollabNet, Codesion Cloud Services. First, thank you for being a Codesion customer!
You describe your situation in terms of "projects," but that's an ambiguous term, and Subversion itself hasn't any notion of it at all. The real consideration here is not Subversion per se, but your build tools and release policy. You want the configuration that best supports what you want to do.
For example, do all these apps and libraries release all at once? Completely independently? Some mix? Is that answer likely to change?
If they all release at once, then there's important value in making it as easy as possible to identify which versions of each app were released with which versions of other apps. That way, bug reports can be verified, fixes implemented, and patches merged all in a coherent, consistent way. To achieve this, I would not use the "/app/{trunk,tags,branches}" structure that several have suggested, but rather stick with the canonical
/trunk/app1
/trunk/app2
/tags/TAGNAME/app1
/tags/TAGNAME/app2
/branches/BRANCHNAME/app1
/branches/BRANCHNAME/app2
structure. This allows you to branch, tag, and merge the whole tree, all apps and libraries, in a single command:
svn cp URL/trunk URL/tags/TAGNAME
On the other hand, if these things are independent, then you're better off with
/app1/trunk
/app1/tags
/app1/branches
/app2/trunk
/app2/tags
/app2/branches
...
This way, for example, tagging one app doesn't affect another.
In a mixed case, you can still achieve the coordinated branching (when it's appropriate), but you'll have to use branching from within your working copy, and perhaps sparse check-outs (if the working copies are large). Alternately, you can tag or branch the whole repository, even though the tag or branch has no meaning for most of it: Subversion tags and branches are cheap to store, and (if you use the URL-to-URL form of "svn cp") cheap to make; the only reason not to tag things with unrelated tags is, it confuses the humans. But that's a pretty strong reason, so a mixed model is best handled with the "app/trunk" structure, to avoid confusion.
You can find good examples of the "/app/trunk" approach in the Apache Foundation repository. All the Apache projects (including Subversion itself) are stored in a single Subversion repository. There are around 100 projects there, and although there are some interdependencies, they're all pretty much managed independently. You can browse around this giant repo (possibly the largest single Subversion repo in the public world), starting at the root of all ASF projects. There's some diversity in practice, there, but one good example is Subversion itself.
Also worth note: in so far as Subversion is concerned, you can always change this stuff. The "tags" and "branches" are really just copies; you're free to rearrange things as you like, when you like. But there are some cautions:
Upvotes: 2
Reputation: 10260
I would recommend the following layout, all in the same repository:
App1\
trunk
tags
branches
App2\
trunk
tags
branches
App3\
trunk
tags
branches
LibraryA\
trunk
tags
branches
LibraryB\
trunk
tags
branches
LibraryC\
trunk
tags
branches
LibraryD\
trunk
tags
branches
Now, I am making a few assumptions about your release schedule. I am assuming that each application and library are released under different schedules. This is a worst-case scenario actually, but my scheme will allow this. Each application needs to have its dependencies pre-compiled and included in its directory in the repository. Here's how App1 would look, given that it has dependencies on Library B and C:
App1\
trunk\
deps\
LibraryB, release 1.1
LibraryC, release 4.3
tags
branches
This means that whenever you branch trunk you will get the necessary libraries along, which greatly simplifies things. Observe that it is the compiled binaries of the libraries, not their sources.
A branch of trunk will use the above versions, and since you're not allowed to modify them, any bugfixes will need to go into App1. Meanwhile, to use the new versions of LibB&C you can update their versions in trunk, when they are released by the libraries team. So, after some time, your repository might look like this:
App1\
trunk\
deps\
LibraryB, release 1.3
LibraryC, release 4.4
tags\
release-1.0\
deps\
LibraryB, release 1.1
LibraryC, release 4.3
branches\
stable-2.0\
deps\
LibraryB, release 1.2
LibraryC, release 4.2
Work in trunk is allowed to use the latest library releases. The release-1.0 is using fixed releases (oldest version here), while the stable branch is using the previous version of the libraries.
The above scheme is something I thought about a lot at my last employer, but never got around to implementing. To make it work you need to have a codebase that is split into applications/libraries and development can take place in parallel. That wasn't really the case for us. But it is a worth-while goal, I strongly believe.
Good luck!
P.S. I strongly recommend against svn:externals. They can make branch management a lot harder. For example, if an external changes and a branch is dependent upon it, you are under risk of messing up that branch (making it uncompilable for example).
Upvotes: 0
Reputation: 11232
I would keep everything in one repository and put each project and library in separate root directory of repository (see Planning Your Repository Organization for details).
Keep in mind that repository structure do not have to be identical to project files structure on disk.
Also I would use svn-externals to share library directories (kept as separate root folders of repository) among various projects.
Upvotes: 2