How to commit subversion revision with every commit in order to refer between two repositories
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:
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.
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
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.
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.
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!
精彩评论