views:

402

answers:

3

Consider software spread in two separate repositories, Pub and Priv. Pub repository is public. Priv is closed. An continuous integration server builds both Pub and Priv when either side changes. It then creates downloadable binaries from Priv that are available to users of Pub. Those binaries are labeled internally and on the file name with the subversion revision.

Question is: How to have programs built from Pub aware of the correct, corresponding Priv revision number so they can auto download and run?

The current solution is for the build server to modify files in Pub to set the revision number of Priv and commit those changes to Pub. However, this presents 2 significant problems:

  1. The build takes a long time so if someone commits changes to Pub (or Priv) during the build, it creates conflicts. That can be forced resolved but the log history looks odd as if those revisions made it into that build.

  2. The subversion log has many entries like "Auto build updated the version." from every time the build run which polutes the otherwise informative subversion log.

So can we do this in a way which doesn't require changing the repository.

Sincerely, Wayne

A: 

I can think of several ways to do this. I assume that for some reason it's not possible to make the revision numbers correspond to each other directly, which would be the obvious and simplest solution.

One way would be to use the commit message to Pub to include a pointer to the corresponding Priv revision, like "Corresponds to Priv r1234".

Another would be to store the correspondences outside the repositories, in some simple database or even text file, that's updated whenever a commit from Priv is pushed to Pub.

Yet another way would be to not do a separate commit, as you currently do, to record the Priv revision, but to add that change to the commit that's supposed to be recorded.

Mark Probst
+1  A: 

You can use a revision property (see the section entitled "Unversioned properties) to store the appropriate revision of Priv against the appropriate revision of Pub. The nice thing about revision properties is that they don't need a commit - so no history pollution.

Revision properties, in Subversion parlance, are attached to a particular revision rather than a versioned folder. These properties, unlike the properties that get attached to files or folders, are non-versioned. They just get applied straight away. Revision properties are added by using the --revprop switch to "svn propset". In TortoiseSVN they are added via the history log (right click a revision then select "Show Revision Properties") rather than the properties of a file or folder and are applied immediately without making a commit.

For example, to associate r1234 of Priv with r6789 of Pub you could do this from a checkout of Pub.

svn propset --revprop -r6789 "priv:version" "1234"

Now when r6789 of Pub is built you can do this

svn propget --revprop -r6789 "priv:version"

to retrieve the appropriate revision number of Priv. In order to cope with other commits that happen after the last Priv build your script would have to "walk" down the history asking each revision for "priv:version" until you get a value. Or you could have a post-commit hook that copies the property to each revision as it occurs.

One gotcha though. You need to have a pre-revprop-change hook that will allow you to work with revision properties. The simplest way is to have it always return 0 so any revprop is allowed. On Windows I do this simply creating an empty "pre-revprop-change.bat" file in the hooks directory. If you take a look at the example hook script that's provided when you create a property, it's actually pretty well documented.

Simon
A: 

Sorry, stackoverflow disallows replying or edit to my post myself or your answers since I wasn't registered when I asked this question. So here are responses...

Simon: Thanks. Why do you propose revision properties don't require committing? The nant build script currently uses revision properties to keep track of branch versions for merging and reintegration (svn's builtin merge ability gets confused too easily). But those revision properties require committing to make it to the central repository and your link refers to the same type of revision properties being used for this. Are you referring to some other type of revision properties?

Critical Skill: Yes, the messages for committing "Autobuild updated to version 0.5.6.1049" is customizable. That commit actually happens in the nant build script which gets executed by CI using Hudson. And, remember, we'd like to eliminate that commit because every commit to Pub gets followed by one (or more) of those automated messages which pollutes the logs.

Mark: re: Commit pointer to Priv. Users who commit to pub have zero access to Priv so they don't know what revision--otherwise a good idea. On the other hand, the automated build does this now when it builds pub and priv but that pollutes the log file with tons of automated commits simply to link the versions w/o any other substantive change to Priv.

Mark: We considered storing the correspondences outside the repositories but that leads to another problem we can't solve. Solve this and you win the answer. The problem is that the pub repository holds software which depends on binaries build from Priv with the exactly corresponding version. So it include an "auto update" feature which connects to the server holding Priv and asks for alist of binaries and downloads them. The key is that the primary parameter to start this download is the version.

Mark: So the question is how can the Pub know which version to download? Right now that is solved to by the situation in the original question. The auto build nant script commits a change to the source code in Pub to include the version number of Priv but that is what pollutes the Pub logs with "Auto build updated the version ..". The auto update tool uses that version if priv to request from web server the Priv binaries. And it all works.

Mark: The secondary problems seems, at first, to be solvable by switching the relationship to have Pub software auto update using it's on version--the version of Pub--and the web server matches it using a separate file to get the most recent matching version of Priv binaries. However, low and behold, there seems to be no practical way to have Pub software know the version from every commit.

Mark: If you put $Rev$ keyword in the auto update code, it only gets updated it that very file was modified. This seems to an "age old" challenge in working with Subversion. It seems a pre-commit hook could update the source code with a version but it seems that only works is someone commits the auto udpate source file in question.

Mark: Your last idea was a little confusing but it sounds like it the same as just mentioned to include the version information with the commit to Pub rather than have an additional automated commit. I like that but can't figure out (after googling and reading forums and posts for more than a day). It seems like an common challenge of how to commit the project wide version along with any ordinary commit to Subversion since it only versions files individually. Even if you use svnversion in a pre-commit hook it only updates the files modified, right? So how does the auto build source code know what version when it runs?

Everyone: Thanks to all of you for your questions and responses. It helps to narrow down the understanding of the question so we can arrive at a solution! S.O. is way cool!

Wayne
I've edited my answer to expand a little bit on what I (and Subversion itself) refer to as a revision property. I think the confusion stems from the fact that there are actually two types of property in Subversion and the page I linked to wasn't great. As soon as I find a better explanation online I'll link to that.
Simon
Thanks. However, while that fixes the problem with the log messages, it loses the versioning ability so that the previous revisions of the source in Pub won't have a way to track which version they match to in Priv.It seems we can't win for losing when it comes to connecting two repositories in Subversion. Still, there MUST be a way.
Wayne
It seems the answer is GIT. GIT uses project-wide versioning instead of file versioning like SVN. It integrates with SVN so that I can internally use GIT to connect to both Priv and Pub SVN repositories and manage the relationship better.Hey, I gathered all the this from reading examples of others who solved the same problem this way and the git documentation.But haven't tried it yet.
Wayne
Wayne. Yes they will. You are setting a property on a *specific* revision of Pub. The property doesn't apply to the repository as a whole, but to a revision.Note the revision number in the command linesvn propget --revprop -r6789 "priv:version"This translates to "give me the revision number of priv stored against revision 6789 of pub"
Simon
Thanks Simon. But I need the this property to be versioned with the code so if we need to rewind and pull out an older version for a customer to fix a bug, it will work. So we need versioned properties but Subversion can only do this per file. Anyway, thanks, due to our unique situation, we gave up and converted to GIT. And (oh my God) is GIT fast. I heard it was fast but never dreamed it would be this fast.
Wayne