views:

774

answers:

9

First, a couple operating parameters:

  • .NET development using Visual Studio 2005/2008
  • TortoiseSVN client

I've only primarily worked with Visual Source Safe and SourceGear Vault source control systems. In each, I map the root of the repository to a local working directory. For example:

$/  -->  C:\source

As long as the local directory exists, I've got my "working copy" (svn) or "working folder" (VSS) set up.

To work on a new project that is already in the source code repository I need to "get the latest" (VSS) version of that project's directory.

When I go into any child directory in the repository and "Get Latest" (i.e. svn checkout) the client will automatically create the complete directory hierarchy for me, mirroring the structure on my local disk. Thus when I get latest of

$/foo/bar/project1

it is created on the drive at

C:\source\foo\bar\project1

In subversion, when I check out a directory, I must specify the working copy directory location. If I want to properly mirror my working copy directory structure to match the repository I have to either manually construct every child directory in the path or do a checkout of the repository root to the working copy root, getting everything in the repository.

Is there a way to get a repository directory down in the hierarchy such that it will be created in a matching local working copy directory structure without all the manual intervention?

This isn't a problem with a small repository, but in most cases, I don't need a large percentage of the source repository. It's imperative that the physical structure is maintained in order for file references to projects and resources not to break. Plus the disk cost of SVN is twice the actual source size given all the working base copies of the files.

I'm currently using Tortoise. Is it possible there are other SVN clients that will do what I'm looking for?

+3  A: 

The Subversion "check out" operation creates a new working copy. What you probably want to do is check out your whole project (which automatically creates the proper directory structure as it is in the repository), then use the Subversion "update" operation. The update will update everything in the specified directory and in subdirectories.

This is perhaps due to a difference in terminology between VSS and Subversion. The Subversion Book is a worthwhile read, particularly the chapter on Basic Usage.

Update: I suppose I'm not quite understanding what your expected use-case is. It sounds like one of the new Subversion 1.5 features you might need is sparse checkouts. This lets you selectively fetch a portion of a repository without necessarily getting the whole thing. It's quite flexible in the options it gives you for managing how much you need to get.

Since sparse checkouts are relatively new, I don't think the SVN book has been updated to include information on this feature. It has been updated, see comments.

Update 2: It sounds like you can construct what you want by checking out the top level of your repository into c:\source with the --depth=empty option. Then, for each subdirectory that you want, update that subdirectory with --depth=empty or --depth=infinity as appropriate.

I believe that all this is rooted in the Subversion design goal of being able to have multiple independent source trees on your system at the same time. With VSS, $/ is configured globally to refer to a specific directory (c:\source) so you can only have one checkout (without a bunch of messing around with the global configuration every time you want to switch).

Greg Hewgill
Looks like it has been added:http://svnbook.red-bean.com/nightly/en/svn.advanced.sparsedirs.html
Peter
Peter: aha, thanks for that!
Greg Hewgill
Greg - I looked over the sparse checkouts feature. While it does look useful, it's still not quite what I need. What I need is kind of a combination: like a sparse branch with a complete node. I.e. just the parent directories, but all the children of the target directory.
Peter
Peter -- what you want seems strange and weird. You may want to adjust how you're using Subversion. I don't see what problem you're trying to resolve with your usage pattern...
Dave Markle
Dave - How is it strange and weird that I want my local working copy of source code to match the hierarchical structure of the same in source code control?
Peter
A: 

But the whole point of the question is that I would prefer not to get the whole entire repository just to create the directory structure on the initial checkout.

Sorry if I wasn't clear that I am starting from a clean, empty working copy location.

And I have read a good portion of the SVN book. However, it doesn't cover these kinds of questions.

Peter
A: 

Not sure why you want to do what you are asking. Most people just create a working local copy, and work on whatever directory they want. That's because of the way Subversion works. It doesn't lock the source code. I started source control by using SourceSafe, so I have a little bit of an idea of what you are going through.

What you probably want is to use the svn:externals property. There are several posts here that talk about this. Here is one of them:

http://stackoverflow.com/questions/125468/how-to-make-svn-only-update-files-but-not-add-new-ones

hectorsosajr
The `svn:externals` property won't create the intervening directory structure he's seeking.
Ken Gentle
A: 

ankhsvn (open source) and VisualSVN (commercial) are products integrated with Visual Studio that may better fit your development model.

Ken Gentle
Ken - I tried ankh. When prompted for the local path, it behaves much like tortoise. There still doesn't seem to be any sense of repository root relativity. I opened a VS sln with 5 projects in it, only the project in the sln's dir was checked out. And no parent branch dirs were created.
Peter
Sorry, Peter. I've used ankh, but in a different way than you described. Couldn't remember if it would do as you asked.I believe the answers posted by icelava or Peter Parker may be your best alternatives. Greg Hewgill says some good things, but I still don't think he understands the question.
Ken Gentle
+1  A: 
  1. First browse your Subversion repository using Repo Browser.
  2. Navigate down the hierarchy to your desired directory; you should end up with a URL showing something like https://subversion:8443/svn/BranchMerge/Branches/TestWeb
  3. Right click on that directory in the left navigation pane, and choose Checkout...
  4. Copy (into clipboard) that directory path "BranchMerge/Branches/TestWeb" from the URL of repository textbox.
  5. Paste that into the Checkout directory textbox to mix and match with the existing path it has, so that it shows your desired hierarchy for your local drive. "C:\source\BranchMerge/Branches/TestWeb"
  6. When you hit OK, a dialog box should appear to ask to auto-create those missing directories.
  7. Agree with it, of course.
icelava
+2  A: 

To answer your bold printed question in short: NO there is no way to create all folders above your project location

The reason for this is slightly longer:

You are thinking in a VSS workflow, where you have 1 workingfolder which has a fixed path on your local directory. So all you can do is check out another project which will create the whole directory structure on your local HD inside your workingfolder.

In SVN you have floating workingcopys you can check out a specific location in your repository to any place you want. You even can move your workingcopy to a different place! Your working copy do not need a fixed location on your HD.

So you do not need to recreate the folderstructure above your project. For your project it also should not make any difference. You are much more flexible by using the SVN workflow of floating workingcopys where the absolute path is unimportant.

However, if you feel more comfortable in using your old VSS-based workflow you can checkout using the --sparse-checkout parameter and recreate the structure manually or write a simple batch file doing this. I cannot see any advantage of this and you will surely forget to do so, if you continue to work with SVN and forgot the old rusty VSS-workflow

Peter Parker
A: 

I'm generally understanding what you all are saying about "how SVN works". Perhaps the problem is not that I'm unclear on that, but I'm falling victim to a higher code organizational problem.

The root of the problem comes from project dependencies. I have many applications that have many dependencies. Because of the hierarchical structure of the .NET projects, the dependencies are expected to be in certain physical locations. So if I am going to start to work on this project:

http://mysvn/svn/foo/bar/project1

that project would go into

C:\source\foo\bar\project1

Now that project depends on another project. In the .NET project file, the project reference is relatively "back referenced":

..\..\..\bar\foo\project2

so the dependency is expect to be in the local working copy at

C:\source\bar\foo\project2

Thus, the parent directory structure is critical.

I can't store dependent project as children of any one specific application/project because they are shared among many projects. So they live in their own locations outside of one particular project tree. Thus, I do need to ensure that any given project (and its dependencies) are checked out to a specific tree location relative to the root of the source tree in order to ensure that the references to the projects don't break or that they don't differ between developers. Otherwise, each of us continually updates references to make them work creating a lot of noise in the source history and constant breaks between developers. Also, then the build server won't have them in the right place either.

I have yet to find any good information about doing .NET development with SVN. There are plenty of open source projects in .NET that use SVN or CVS. However, those that I have looked at always seem to be in a fairly isolated structure such that all the different projects fall under a single source tree location. This makes it trivial to get everything that is needed because you can simply check out one path recursively and get everything you need.

I'd be very interested to hear from anyone who does enterprise development in .NET using SVN with many shared projects that cross project storage location boundaries.

It is beginning to feel like the only solution that would work in a team is to simply check out the entire repository to ensure the structure is correct and consistent. That is unfortunate for a repository that has many gig of source.

Peter
There is a definite communication problem with responses to your question. I rarely do Visual Studio work, but I know what you mean about references to other projects and how they're created. Is there _any_ way to make the base directory a property or variable like ${base}\project1 in the IDE?
Ken Gentle
Ken - Unfortunately there is no way that I know of to specify base locations to referenced projects. VS does this all for us. Usually, they are back references, but I've seen them be explicit full paths. But I've not seen any way for the user to control this.
Peter
A: 

Ok, first and foremost, the way you're working is like to cause problems, ultimately.

The principle your looking for is that each project should have a trunk/branches/tags structure which is independant of any other project. And that checking out trunk automatically gets all the code, including dependencies, which will be enough to build your project.

You're clearly not in that kind of position, and moving to it will take some effort. However, there is a workaround that you can use to get you going as you want, using externals.

  1. In Repo-browser, create a new tree folder in the root, perhaps "Projects".
  2. In this Projects folder, create a folder for your project "MyProject".
  3. On this folder, right click it and edit the properties, add a new property called "svn:externals" - it'll be in the list.
  4. Use this property to define the tree required for your project.
  5. Checkout http://svnserver/svn/Projects/MyProject and the whole tree will be retrieved.
  6. Work as normal.

An example of the svn:externals property might be:

http://mysvn/svn/foo/bar/project1 foo/bar/project1
http://mysvn/svn/bar/foo/project2 bar/foo/project2

Although it would be better to use relative references as detailed in the redbook.

Jim T
Thanks for the suggestion Jim. As I recently converted our dev team to SVN from VSS I've had to think about this problem again (and again, and again). I came up with a similar idea. I thought of creating a repo path for "projects" that is basically just an empty set of directories (one for each application solution) that contain externals to all the necessary projects that make up each solution, essentially resulting in a flat tree of projects. However this would require breaking all the inter-project references to favor the flat structure. Maybe I can work with your suggestion.
Peter
A: 

I seemed to have found a suitable solution to my problem.

Using TortoiseSVN, the "Update item to revision" action within the repo browser can be used to locally reconstruct the repository's folder structure for an arbitrary repo path.

Detailed steps are:

  1. Create a local folder to be the working copy root of the highest repository folder for which you need to maintain physical folder structure
  2. Do a shallow checkout of the repository root (checkout, select "Checkout Depth" of anything except "Fully recursive")
  3. Launch repo browser from the working copy folder
  4. Find repo path you want to get
  5. Right-click on desired folder, choose "Update item to revision"
  6. Leave defaults of HEAD revision and "Working copy" update depth, click OK

This will update your working copy with the contents of the chosen repo path including all the parent directories up to the start of the checkout working copy thus mirroring the folder hierarchy of the repository in your working copy.

Notes on the "Update item to revision" context menu option:

  • This option only appears on repository paths that don't already exist in the local working copy
  • It looks like leaving the "Update Depth" to the default of "Working Copy" is fine for getting all contents of the chosen path. (Rather than having to explicitly select "Fully recursive".)
Peter