Question

From what I understand about transactions in Subversion this should be possible in principle, but I don't know any tool that supports it.

The background is that we are discussing a migration from PVCS Dimensions to Subversion, and the main feature cited as missing in Subversion is "Design Parts". A design part is an arbitrary collection of files that can be handled together, e.g. all the source files needed for a subproject.

One idea to replace this is by copy operations in a Makefile, which copy the relevant files into a branch. But if all files are copied separately this may lead to a lot of revisions, which may clutter the history, so it would be nice to avoid that.

EDIT: Some more background information:

The project consists of several (5-10) subprojects which are released separately, but which share some common source files and external libraries imported from other projects.

One reason cited for the design parts is restricting dependencies on source files, another is for managing the products of subprojects, so that all of them can be updated in version control in one operation. Both kinds of files are somewhat sprinkled across directories.

We are about 5 developers on the project.

Was it helpful?

Solution

You can make the copies in a working-copy and commit them all at once later. That creates only one revision.

With the command-line-client it could look like that:

svn copy file1 directory
svn copy file2 directory
svn copy file3 directory
svn commit

The main downside is you need a working-copy and this working-copy has to include source- and target-directory.

OTHER TIPS

There is a tool svnmucc which does exactly this, without requiring a working copy:

http://subversion.tigris.org/tools_contrib.html#svnmucc_c

You can use: svn copy FROM_URL1 FROM_URL2 URL_TO

For example:

svn copy svn://192.168.1.50/trunk/folder1 svn://192.168.1.50/trunk/folder2 svn://192.168.1.50/tags/MY_TAG

This is fairly interesting, I've just had a quick read on design parts, from what I can gather, by effectively branching the files individually into an arbitrary structure, you're going to be heading for a world of pain when you start to merge things back to their original location (and the merge probably won't be done in a single commit across all the files).

But I think you can do a similar thing to design parts in subversion with a bit of tweaking:

First, a design part can be simulated using externals (1.6 allows externals to point to files as well as directories). To do this, you could setup your project heirarchy like this:

/project1
 /trunk
  /doc
   /design1
   /release2
  /src
   /subproject1
   /subproject2
 /tags
 /branches
 /parts
  /part1
  /part2
  /part3

Each parts folder would only contain an "svn:externals" property which brings in the appropriate files for that part into the appropriate sublocation, like:

svn:externals

../../trunk/src/subproject1       src/subproject1
../../trunk/doc/release2          doc/release2

You then checkout the part, rather than trunk, and you get a working copy that contains just the files you want in the structure that the part defines, and when you commit, you're going straight into trunk - no merging required here.

You can also baseline your parts by first branching the entirety of trunk (cheap and quick), and then changing your part externals to point to the branch instead of the main trunk. This doesn't increase the size of the repository, and your working copy keeps exactly the same structure, you're just sourcing all your files from the branch rather than trunk. Any updates to that part also goes against the branch - merging the changes of the part is just a bog standard re-integration merge of the branch back into trunk, which is standard svn practice.

Managing the definition of parts gets more interesting, since in the scheme above, each part is defined manually and they're not hierarchical. You'd need some form of script (perhaps makefile) that knows the parts hierarchy and given a part name, can build the appropriate externals definitions which can then be applied to a parts directory.

So while subversion doesn't explicitly provide the abstraction layer of parts, it can be modeled manually fairly accurately - you're only limited by the capabilities of svn:externals and the scripts which you use to manage them.

Why don't you put your subproject into an own subdirectory.

Project
   |
   ---> Subproject 1
   ---> Subproject 2
   Files from project.

In this way you could always operate on a complete subproject.

Here we have:

Project
   |
   ---> common Files
   ---> Subprojects...

If all projects were in their own repositories, svn externals may do the trick

I was facing similar problem: how to copy several files, scattered in repository into a tag and make it fast in one transaction thus one revision. Simplest way is to create temporary Working Copy directory, copy all needed files there and then copy local Working Copy to remote repository and remove temporary directory:

svn mkdir TMP_DIR
svn mkdir TMP_DIR\MY_TAG
svn cp --parents src\test\File.txt TMP_DIR\MY_TAG\src\test\File.txt
svn cp --parents src\test2\File2.txt TMP_DIR\MY_TAG\src\test2\File2.txt
svn cp -m "comment" TMP_DIR\MY_TAG "http://myrepohost/myrepo/tags/"
svn rm --force TMP_DIR

hope that helps.

Your workflow / code organisation is wrong:

if you've got shared code between separate packages, this clearly belongs into a separate one. one tree per package.

putting several packages (of specific versions) together into some environment (eg. a larger software product consisting of several, possibly optional, components) belongs onto an separate layer above: the distro, and is handled by the distro's package management infrastructure.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top