views:

570

answers:

4

Most of our projects use a lot of common code. We are (finally) moving towards a system where we are managing that shared code in a uniform way. We treat the shared code as a separate project in SVN, then reference it as an external. However, we tend to point the external libraries to development branches or even the trunk while the project is under development, due to the inevitable gotchas from porting the libraries from one usage to another.

As a result, we have been making mistakes when tagging files for release or internal milestones. Once in a while we will tag a project without ensuring that all the externals have been tagged first. How can we solve this problem? I'm looking for ways to reduce the possibility of a mistake or to recover/repair after making a sloppy tag like this. Ideally the solution would be a way to make SVN enforce the current policy, but I'm interested in any experience with problems like this.

+4  A: 

I would use two strategies to deal with that problem

  1. automate the tagging. Create a shell script that changes all svn:externals to a fixed revision/release tag before creating the tag on the project.
  2. have a script that checks existing tags for consistency. It's actually possible to reconstruct the state at tagging time even when you the external linked into the trunk: as you know the date and time when the tag was created, you can also find out what trunk revision was active at that point, and either modify the external to point to a specific revision of trunk, or to the release that was current at the time when the tag was made.

In addition, you can also come up with a pre-commit hook that checks whether a tag is being created, and whether all externals point to fixed revisions, rejecting the commit if this is not the case.

Martin v. Löwis
A: 

It sounds trite, but surely the best thing to do is not reference development branches of libraries. You'd not do that if it was a third-party library, and it's not a good idea to do so with your own libraries either.

It might appear to be more work, but if you come across a bug in a referenced library, fix it, tag a new release and reference that new tag in your project.

If you really must reference development branches of libraries, you could use a pre-commit hook script that determines when you're doing a tag and ensures that all the referenced externals are tagged versions too: then the script can flunk the commit if that's not the case. It's quite a hit to take every time you do a commit though.

Richard Turner
It is true that the best thing to do would be to not reference development branches of libraries. However, this is not a practical change that I can make because I can't control the actions of my coworkers or guarantee that no mistakes are made.
Ben Gartner
+1  A: 

We also want to enforce the policy of freezing externals that are copied to tags, but haven't quite implemented it on the server yet.

The idea is for the pre-commit hook to use svnlook command with the transaction number to check for any "tags/" destination in a copy. In case of hit, the properties have to be examined and searched for any svn:externals. Possibly other properties to allow an overriding of the policy.

The obvious question is the load on the server, and which language to use for that hook. Normally SVN comes with better Python Ctypes bindings, unfortunately last time I checked it was not available for Windows (neither compilable as is for this target). But the pysvn module might have just enough to do that. Other than this language, bash scripts could work but would be messy and not so portable. Or pure C...

RedGlyph
A: 

while not treating your internal libraries just like your external ones? If you Apache Ivy (resp. Maven), it would be quite easy to publish your libraries into a central repository (with a version number, 1.0 or SNAPSHOT_20091005) and just import them using the standard Ivy (resp. Maven) mechanism.

That way, you remove all problems with SVN externals. Of course, each project will need to use tags before creating a release, but that's "release 101".

Vladimir