I'm looking into svn externals for my company, and it seems like it would be a good feature for us to use. We have several products that often reference shared components, but have a bad habit of falling behind into older versions and even differently branched codebases sometimes.
I've read a decent bit about how they work now, and I think I understand the concept OK. What I'm not 100% sure on is how different revisions of multiple repositories link together.
Let's say I have a Product and a Library. The Product is built against the Library, so its repo has a svn:externals property that links to the Library source. In the absence of a specific version in the svn:externals definition, when I check out HEAD of Product I also get HEAD of Library.
I build several versions of Product over the years, each time referencing the latest version of Library. One day though I have to go back and check out Product version 1, by manually selecting the correct revision. When I do so, which version of Library do I get, HEAD or the revision that I used when I built it the first time?
Hopefully I've been a good developer and remembered to tag every version of Product that I release. When I apply my tag 'Product-1-0-0' to the repository, does the correct revision of the Library repository get tagged too? If I later check out Product based on the tag 'Product-1-0-0', does the correct revision of Library get checked out with it?
Yes it will, assuming you provide an explicit revision number in your externals, as suggested in the docs. Otherwise it will use HEAD revision of externals referenced.
Just watch out for file based svn:externals in 1.6. They look very useful, but I just hit this bug today :(
What you have to watch out for with
svn:externals
is that you need to explicitly specify the revision if you want something other than trunk. Google "pinning svn:externals" for the details. If you are using a fairly modern version, 1.5 or newer IIRC, then relative externals are at least supported. Older versions, like the one that I am currently using, requires us to explicitly pin the revision using the-rNNNNN
option on thesvn:externals
property for every damned folder.We ended up using a modification of a perl script named
svncopy.pl
from tigris.org to do all of our branching and tagging. It's not that bad but I wish that we had known how much work it was before we decided to use them so heavily.You can use date specifiers to ensure you get corresponding revisions when you update.
We've done it for a tool that runs PC-Lint; we like to run it on each revision so that we can diff the results.
It's a bit obnoxious in its implementation -- we:
svnversion
)svn info
)svn log
)svn update -r {sometimestamp}
)(Complexity worthy of Rube Goldberg, isn't it? Upvotes and undying gratitude for anyone who can suggest a better solution.)
You may also be interested in the svn book's section on Peg and Operative Revisions, which I've just discovered -- this seems to be a relatively new addition.
This article addresses the question nicely...
http://www.simple-talk.com/dotnet/.net-framework/tortoisesvn-and-subversion-cookbook-part-4-sharing-common-code/
Seth
You should read up on dependency managers - I'm not sure what your platform is, but ivy and maven solve this problem in a much cleaner manner.
svn:externals are not versioned in subversion. if someone changes the revision or tag of one of your externals you have no way of knowing what it was prior to the change.