Domanda

We have a Subversion setup that makes fairly extensive use of svn:externals (more than 5 external references in one project, and while most are in the same repository, one or two are in a different repository but still on the same server). Currently, the svn:externals properties are set up in a way where they have the full URL of the referenced project (i.e. "https://[server]:[port]/svn/Repository1/Projects/...)

Recently, I have set up an SVN mirror using svnsync which backs up our repositories to an external off-site facility. We need the ability to do read-only checkouts from those mirrored repositories at the remote site, which seems to work fine for the most part except when it tries to pull the externals, it still references our local on-site server.

Not sure if this is the best way to go about it, but I would like to set up some sort of post-commit hook at the remote location which would modify the properties of svn:externals and replace the hostname of our local server here with the hostname of the remote server there. This hook would run after each commit made by svnsync.

Ideally, we would like to avoid modifying our svn:externals properties at the main repository to not include the server name.

Has anyone ran into this issue before? What is the best way to go about it?

È stato utile?

Soluzione

You must understand that svn:externals are a property on a file, and modifying them requires a commit. If you have a mirror, and you modify the svn:external, you're creating a new remote version and breaking your mirror. The revisions will no longer line up.

Although it seemed like a neat idea at the time, svn:externals can be very bad in a project. Imagine a project like this:

http://vegibank.com/svn/trunk/project1

And I have on this directory an svn:external

$ svn pset svn:external "^/trunk/project2/foo foo" .

I do this because the foo directory is a shared set of files for multiple projects.

Now, I create a tag for project1:

$ svn cp http://vegibank.com/svn/trunk/project1 http://vegibank.com/svn/tags/1.2.3

Looks nice -- except the project1/foo directory isn't tagged. It's linked to the trunk of project2/foo.

My assumption with a tag is that the tag never changes, but this isn't true. Work is still being done on project2/foo on trunk, and that changes what my tag represents. If I have a bug in release 1.2.3, and I decide to checkout my tag to see what could be the problem, I'm not getting necessarily what I released in project1/foo -- I'm getting the latest from trunk.

A better way to handle this is to create a release repository, build the code that's common between various projects as some sort of pre-compiled artifact and have your project depend upon that version of that artifact. It ends up being no different than a C program dependent upon a particular version of libz.so or a Java project dependent upon version 1.6 of org.apache.commons.httpd.

This will eliminate the use of svn:externals and simplify your mirroring. You could mirror the release repository as well as the source repository.

If you insist upon using svn:external, don't use the full URL. Instead, use relative URLs.

For example, if you had setup your `svn:external above instead of this:

$ svn pset svn:external "^/trunk/project2/foo foo" .

to do this:

$ svn pset svn:external "../project2/foo foo" .   #property on ^/trunk/project1

Now, if I create a tag like this:

$ svn cp http://vegibank.com/svn/trunk http://vegibank.com/svn/tags/1.2.3

I'm tagging both project1 and project2. Now, my svn:external refers to http://vegibank.com/svn/tags/1.2.3/project2/foo.

What you need is a way to enforce svn:externals in this way, and you can use a pre-commit hook to reject any commit that has a svn:external set that references the trunk or branches directory without either specifying an actual revision.

Altri suggerimenti

What version of svn are you running? If you're current you can avoid putting the hostname in the svn:externals read the redbook specifically check out starting the external with /

you should strongly consider getting out of the svn:externals morass... especially if the links point to the same repo... you're branching and tagging are harder. I've seen a lot of svn implementations and svn:externals is usually a bad smell.

Also, as a general rule I think it's sub-optimal to have a post-commit hook that changes what the developer meant to do. Though in this case you'd likely be fine.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top