Can you do a partial checkout with Subversion?

tortoise svn sparse checkout
svn checkout exclude directory
svn export
svn checkout terminal
svn checkout folder
svn checkout trunk
svn modify checkout depth
svn checkout not recursive

If I had 20 directories under trunk/ with lots of files in each and only needed 3 of those directories, would it be possible to do a Subversion checkout with only those 3 directories under trunk?


Subversion 1.5 introduces sparse checkouts which may be something you might find useful. From the documentation:

... sparse directories (or shallow checkouts) ... allows you to easily check out a working copy—or a portion of a working copy—more shallowly than full recursion, with the freedom to bring in previously ignored files and subdirectories at a later time.

Can you do a partial checkout with Subversion?, Subversion 1.5 introduces sparse checkouts which may be something you might find useful. From the documentation: sparse directories (or  The checkout operation is not possible on the single file (but it will be in 1.7). Still, there are at least two simple ways to get single file with subversion. Svn before 1.7 supports only svn export on the single file: ⚠ That is not a checkout, you just get one file. It will not be under version control.


Indeed, thanks to the comments to my post here, it looks like sparse directories are the way to go. I believe the following should do it:

svn checkout --depth empty http://svnserver/trunk/proj
svn update --set-depth infinity proj/foo
svn update --set-depth infinity proj/bar
svn update --set-depth infinity proj/baz

Alternatively, --depth immediates instead of empty checks out files and directories in trunk/proj without their contents. That way you can see which directories exist in the repository.


As mentioned in @zigdon's answer, you can also do a non-recursive checkout. This is an older and less flexible way to achieve a similar effect:

svn checkout --non-recursive http://svnserver/trunk/proj
svn update trunk/foo
svn update trunk/bar
svn update trunk/baz

Sparse Directories, For example, svn checkout creates a working copy with every file and Here are the depth values that you can request for a given Subversion operation:. ICEM products from CVS to subversion. Some historic directory structures with up to 800 source files in one directory must be preserved (the management does not assign sufficient priorities for a cleanup). Some build tools also require that you check out directories above the ones you are working in, but obviously you only want


Or do a non-recursive checkout of /trunk, then just do a manual update on the 3 directories you need.

SVN and large repositories: Sparse checkout - OpenEarth, In order to create a sparse checkout, you use the same menu of TortoiseSVN you would use for a usual (fully recursive) checkout; the only  Subversion checkouts are different: they mix the repository data in the working directories, so there is a working directory for each branch and tag you've checked out. For repositories with many branches and tags, checking out everything can be a bandwidth burden, so you should start with a partial checkout.


I wrote a script to automate complex sparse checkouts.

#!/usr/bin/env python

'''
This script makes a sparse checkout of an SVN tree in the current working directory.

Given a list of paths in an SVN repository, it will:
1. Checkout the common root directory
2. Update with depth=empty for intermediate directories
3. Update with depth=infinity for the leaf directories
'''

import os
import getpass
import pysvn

__author__ = "Karl Ostmo"
__date__ = "July 13, 2011"

# =============================================================================

# XXX The os.path.commonprefix() function does not behave as expected!
# See here: http://mail.python.org/pipermail/python-dev/2002-December/030947.html
# and here: http://nedbatchelder.com/blog/201003/whats_the_point_of_ospathcommonprefix.html
# and here (what ever happened?): http://bugs.python.org/issue400788
from itertools import takewhile
def allnamesequal(name):
    return all(n==name[0] for n in name[1:])

def commonprefix(paths, sep='/'):
    bydirectorylevels = zip(*[p.split(sep) for p in paths])
    return sep.join(x[0] for x in takewhile(allnamesequal, bydirectorylevels))

# =============================================================================
def getSvnClient(options):

    password = options.svn_password
    if not password:
        password = getpass.getpass('Enter SVN password for user "%s": ' % options.svn_username)

    client = pysvn.Client()
    client.callback_get_login = lambda realm, username, may_save: (True, options.svn_username, password, True)
    return client

# =============================================================================
def sparse_update_with_feedback(client, new_update_path):
    revision_list = client.update(new_update_path, depth=pysvn.depth.empty)

# =============================================================================
def sparse_checkout(options, client, repo_url, sparse_path, local_checkout_root):

    path_segments = sparse_path.split(os.sep)
    path_segments.reverse()

    # Update the middle path segments
    new_update_path = local_checkout_root
    while len(path_segments) > 1:
        path_segment = path_segments.pop()
        new_update_path = os.path.join(new_update_path, path_segment)
        sparse_update_with_feedback(client, new_update_path)
        if options.verbose:
            print "Added internal node:", path_segment

    # Update the leaf path segment, fully-recursive
    leaf_segment = path_segments.pop()
    new_update_path = os.path.join(new_update_path, leaf_segment)

    if options.verbose:
        print "Will now update with 'recursive':", new_update_path
    update_revision_list = client.update(new_update_path)

    if options.verbose:
        for revision in update_revision_list:
            print "- Finished updating %s to revision: %d" % (new_update_path, revision.number)

# =============================================================================
def group_sparse_checkout(options, client, repo_url, sparse_path_list, local_checkout_root):

    if not sparse_path_list:
        print "Nothing to do!"
        return

    checkout_path = None
    if len(sparse_path_list) > 1:
        checkout_path = commonprefix(sparse_path_list)
    else:
        checkout_path = sparse_path_list[0].split(os.sep)[0]



    root_checkout_url = os.path.join(repo_url, checkout_path).replace("\\", "/")
    revision = client.checkout(root_checkout_url, local_checkout_root, depth=pysvn.depth.empty)

    checkout_path_segments = checkout_path.split(os.sep)
    for sparse_path in sparse_path_list:

        # Remove the leading path segments
        path_segments = sparse_path.split(os.sep)
        start_segment_index = 0
        for i, segment in enumerate(checkout_path_segments):
            if segment == path_segments[i]:
                start_segment_index += 1
            else:
                break

        pruned_path = os.sep.join(path_segments[start_segment_index:])
        sparse_checkout(options, client, repo_url, pruned_path, local_checkout_root)

# =============================================================================
if __name__ == "__main__":

    from optparse import OptionParser
    usage = """%prog  [path2] [more paths...]"""

    default_repo_url = "http://svn.example.com/MyRepository"
    default_checkout_path = "sparse_trunk"

    parser = OptionParser(usage)
    parser.add_option("-r", "--repo_url", type="str", default=default_repo_url, dest="repo_url", help='Repository URL (default: "%s")' % default_repo_url)
    parser.add_option("-l", "--local_path", type="str", default=default_checkout_path, dest="local_path", help='Local checkout path (default: "%s")' % default_checkout_path)

    default_username = getpass.getuser()
    parser.add_option("-u", "--username", type="str", default=default_username, dest="svn_username", help='SVN login username (default: "%s")' % default_username)
    parser.add_option("-p", "--password", type="str", dest="svn_password", help="SVN login password")

    parser.add_option("-v", "--verbose", action="store_true", default=False, dest="verbose", help="Verbose output")
    (options, args) = parser.parse_args()

    client = getSvnClient(options)
    group_sparse_checkout(
        options,
        client,
        options.repo_url,
        map(os.path.relpath, args),
        options.local_path)

Checking Out A Working Copy, To obtain a working copy you need to do a checkout from a repository. If you check out a sparse working copy (i.e., by choosing something other than fully  SVN Partial Checkout. GitHub Gist: instantly share code, notes, and snippets.


If you already have the full local copy, you can remove unwanted sub folders by using --set-depth command.

svn update --set-depth=exclude www

See: http://blogs.collab.net/subversion/sparse-directories-now-with-exclusion

The set-depth command support multipile paths.

Updating the root local copy will not change the depth of the modified folder.

To restore the folder to being recusively checkingout, you could use --set-depth again with infinity param.

svn update --set-depth=infinity www

Control Repository Size with SVN Sparse Checkout, The beauty of SVN sparse checkout is you can mix depths. For folders That legacy is still felt today in the tooling we use to run the business. Sorry for duplicate mails. The method pointed out on that URL can ignore directories that I don't care, but I need do an unwanted checkout for C/ from the real repos at the first time, of course, it's not a big problem, just not so intuitive.


Partial checkout using externals - SVNForum.org, The checked directories are indeed being copied to the local repository but the externals don't get copied. If I do the same but selecting Fully  Unlike CVS, Subversion doesn't really support the notion of single-file checkouts. In other words, you can't just checkout some of the files in a directory and not others. Subversion 1.5 will support something called sparse directories which at least allows you to skip checkout all the way down your directory hierarchy.


Sparse Directories, A regular svn checkout operation will give us a working copy of the whole tree: Here are the depth values that you can request for a given Subversion  Checkout the specified directory, including all files but do not checkout any child folders. Only this item. Checkout the directory only. Do not populate it with files or child folders. Working copy. Retain the depth specified in the working copy.


Subversion sparse checkouts, With svn's sparse directory support, you can do the following, svn checkout --​depth=immediates http://www.example.com/svn/myrepo. This checks out the  Checking out the anonymous SVN version of VisIt. Checking out VisIt's source code from NERSC requires that you have an account and ssh access. However, a read-only mirror of the VisIt SVN repository as also available so you can checkout anonymously over http. If you want to check out the sources from the mirror,