Sparse Directories

By default, Subversion commands on directories act in a recursive manner. For example, svn checkout creates a working copy with every file and directory in the specified area of the repository, descending recursively through the repository tree until the entire structure is copied to your local disk. Subversion 1.5 introduces the --depth option which allows you to easily checkout all or part working copy with the freedom to bring in previously ignored files subdirectories at anytime. For example, say we have a repository with the following structure:

$ svn co file:///var/svn/repos mom
A    mom/son
A    mom/son/grandson
A    mom/daughter
A    mom/daughter/granddaughter1
A    mom/daughter/granddaughter2
A    mom/daughter/fishie.txt
A    mom/kitty1.txt
A    mom/doggie1.txt
Checked out revision 1.

Now, let's checkout the same tree with, but with no children at all:

$ svn co file:///var/svn/repos mom --depth=empty
Checked out revision 1

Now let's dig a little deeper and checkout the tree with only the files in the top-level directory:

svn co file:///var/svn/repos mom --depth=files
A    mom/kitty1.txt
A    mom/doggie1.txt
Checked out revision 1.

As you can see, we got only the files in the top-level directory, and not the directories. If we want the files and directories in the top-level directory, but not the children in those directories, we can use the immediates argument:

svn co file:///var/svn/repos mom --depth=immediates
A    mom/son
A    mom/daughter
A    mom/kitty1.txt
A    mom/doggie1.txt
Checked out revision 1.

This retrieves the subdirectories in the top-level, but sets the depth of each of these subdirectories to empty.

While we've used svn checkout as an example here, you can use the --depth option with many other Subversion commands. Here's a brief overview of what each depth argument does (See Chapter 9, Subversion Complete Reference for details on which commands use the --depth option).

--depth=empty

Include only files or subdirectories that are already in your working copy (which means none if you're doing a fresh checkout).

--depth=files

Increase the depth of the current directory to include files, but not subdirectores

--depth=immediates

Increase the depth of the current directory to include both subdirectories with --depth=empty and files.

--depth=infinity

The default behavior. Increases the depth of the current directory to, well, infinity (what indeed did you expect?)

To illustrate how you might use sparse directorise, let's say that you have a repository with 37 top-level projects:

trunk/project1
trunk/project2
trunk/project3
...
trunk/project36
trunk/project37

If you're working on project23 and it has dependencies on project14 and project29, it would be convenient to checkout those three projects as part of a cohesive working copy without sucking down the other 34 projects. To do this, you could perform the following series of actions:

$ svn checkout file:///var/svn/repos/trunk uberproject --depth=empty
...
$ cd uberproject
$ svn update project14
...
$ svn update project23
...
$ svn update project29
...

Now you have a minimally-sized working copy that will allow you to commit changes to all three of these projects at once.

Another time where sparse directories are useful is when you've just done a merge into your working copy and you'd like to see the property modifications that will be recorded as part of the merge, running svn diff on your directory will pull down all the changes in your working copy recursively, however, if you use --depth=empty, it will only show the property modifications (i.e. only the changed mergeinfo) on the root directory of your working copy.