mirroring a subfolder between two writable SVN rep

2019-07-17 15:46发布

问题:

I have a situation I'm trying to cope with involving my company's SVN server. We keep all of our important code in a locked-down server (we'll call this the "dev" server). There are some files that need to be edited by users outside the corporate network, so we have another SVN server (the "global" server) which is accessible outside the firewall and contains copies of those directories containing the files needed externally. If it matters, the folder structure of the global server is a subset of the dev server (i.e. it's just a few select files/directories, but all have the same relative paths, etc). I've included a brief explanation of why we're trying to do this at the end of the post if you want to read it, but trust me, it has to be done on two separate servers.

At first glance, svnsync seems ideal for this job, but it has the unfortunate problem of requiring that it be the only thing modifying the destination repository. Obviously, that will not work since our dev repository is heavily used.

It seems to me that there are two solutions, and neither of them is a good solution. I'm hoping someone can help me tweak one of these, or better yet provide an alternative.

  1. My first idea is to use externals in the dev server, but this has some problems. Most notably, an external will follow the head revision (we don't want to set it to a specific revision as that would defeat the point), and therefore if we pull up older versions of the dev repo, the externals definitions will still point to the head of the global repo, instead of to what the global repo looked like at the age of our old revision -- thus we will not be able to recreate old releases simply by checking out an old revision.
  2. The other solution is to have a cron job periodically export the latest revision(s) from the global repo and overlay those changed files onto a working copy from the dev repo, then commit the changes. Probably this overlay-and-commit step would be done using the svn_load_dirs.pl script that comes with SVN. This would ideally be done as a post-commit hook on the global repo, but again for firewall reasons, the global server cannot access the dev server, so it must be performed by a machine inside the firewall (probably the dev server machine itself). This approach has the drawbacks of: the dev server can be out of date by as long as the interval on the cron job, and if someone accidentally commits a change to the dev server, their change will get stomped on. (as an aside, if someone can come up with a method of bi-directional syncing, that would be awesome!)

I'm currently leaning towards option 2 because it is seems to get me as close to what I need as possible, but it's still quite a bad option. It's also essentially what we're doing currently, with a human instead of a cron job. My apologies for the long post. Thank you very much for any help you can provide.

Explanation of why: We need these shared files to exist in the dev server directory hierarchy because they are a required part of our software, so builds, testing, etc must have them. I cannot expose the dev server through the firewall -- I have tried to convince the powers that be and failed. I have made it very clear to the decision makers that having two separate servers for this is not how SVN is intended to be used and that there will likely be problems. To help mitigate some of the problems we have foreseen, only the global server will be writable. The dev server's copy of the files will be conceptually read only (only modified when changes are synced from the global server), but I don't think I can actually enforce that read-only policy with SVN access controls because some of the files in that directory structure are not going to exist in the global repo, and thus need to be editable in dev, so I can't blindly make the thing read only. Setting read-only on a per-file basis seems unmaintainable, as there are hundreds and they are often added and deleted.

回答1:

You could try to set up a write-through proxy, so that all writes on your public repository are automatically forwarded to the private server.

I've never done this, but here's some documentation on the subject.



回答2:

Rather than get complicated here on the source control it may be worth thnking on splitting the two repos (removing the code that lives in global from dev) and then having the build of dev consume builds of global. Since your internal people will be able to commit to both, and having the same code live in both is forever goign to be difficult.

You didn't mention the languages tooling involved... so it's hard to know how this is going to fit. Think a build on global publishing the artifact(s) and then the build of global resolving that dependency.

One thing you didn't mention in alternative 2, you're going to loose audit trail as the user that commits to global won't be the user that overlays and commits to dev.