It's often true that users want to checkout some, but not all, of a
large repository. Currently, it's easy to checkout a single subdirectory
using Subversion. However, if you want to checkout a group of
subdirectories, and manage this group as a single working copy, you're
going to run into some major challenges.
In the past year, we've seen two proposals for managing large working
copies. Last year, Ben Reser proposed creating two new subcommands,
called 'svn include' and 'svn exclude', which allow you to configure
which directories are pulled in by 'svn update' [1]. This year, Eric
Gilespie proposed to instead add a depth parameter to the 'update'
command [2].
Both Ben and Eric's proposals suffer from a similar problem: they don't
actually make it easy to checkout a group of subdirectories. With either
proposal, you're forced to execute a long series of commands (or a long
series of options) in order to check out a group of subdirectories as a
single working copy.
I'd like to propose we add full-fledged viewspecs to Subversion. Here's
how such a feature might work:
To checkout a working copy from the server, which only includes the
specified files:
svn checkout --viewspec my-view.txt svn://server/trunk
Edit the current viewspec (in your favourite editor):
svn viewspec
Save the current viewspec to a file:
svn viewspec > my-view.txt
Load a viewspec from a file:
svn viewspec < my-view.txt
Add the 'contrib' directory to the viewspec:
svn viewspec --add contrib -R
Remove contrib/client-side/svnmerge.py from the viewspec:
svn viewspec --remove contrib/client-side/svnmerge.py
===================================================================
HOW TO SPECIFY WHAT FILES ARE CHECKED OUT USING A VIEWSPEC:
1. +foo/... --> Checkout 'foo', and all subdirectories.
2. +foo/* --> Checkout the immediate children of 'foo'. Don't
download subdirectories.
3. -foo/... --> Don't download anything inside 'foo'
4. -foo/* --> Don't download the immediate children of 'foo'.
5. +bar --> Download the file 'bar'. (If 'bar' is a directory,
an error will be reported.)
6. -bar --> Don't download the file 'bar'. (If 'bar' is a
directory, an error will be reported.)
===================================================================
AN INTRODUCTION TO VIEWSPECS
Let's say you're just an average Subversion user. You used Subversion
to checkout 'http://svn.collab.net/repos/svn/trunk', and you type
'svn viewspec', because you're curious how the command works.
When you type svn viewspec, a template shows up in your editor, with
a few lines of helpful comments, which explain briefly how viewspecs
work, and point to documentation. Underneath, you see a single line,
which indicates that every file in the current directory is included.
+...
Following the instructions, you decide to exclude the 'contrib',
'tools', and 'www' directories. You do so by adding the following lines.
-contrib/...
-tools/...
-www/...
You press enter, and voila! The contrib, tools, and www directories
disappear.
Later on, you decide to switch over to work on the 1.3.x branch. You
type:
svn switch http://svn.collab.net/repos/svn/branches/1.3.x
When you switch branches, your viewspec is maintained, and the
'contrib', 'tools', and 'www' directories are still not pulled
down.
Later on, you decide to checkout the same viewspec on a different
machine. To transfer your viewspec, you type:
svn viewspec > my-view.txt
scp my-view.txt some-other-machine:~
On the other machine, you type:
svn checkout --viewspec my-view.txt \
http://svn.collab.net/repos/svn/branches/1.3.x
After typing that command, you're presented with exactly the same
view of the repository.
===================================================================
EXAMPLE #1: Download only foo/images and bar/images
+foo/images/...
+bar/images/...
===================================================================
EXAMPLE #2: Download everything but foo/videos and bar/videos
+...
-foo/videos/...
-bar/images/...
===================================================================
EXAMPLE #3: Download files in the root directory, as well as files
in the 'subversion' and 'build' directories. Don't
download anything else.
+*
+subversion/...
+build/...
===================================================================
EXAMPLE #4: Download everything except the 'contrib', 'doc', 'notes',
'tools', and 'www' directories.
+...
-contrib/...
-doc/...
-tools/...
-www/...
===================================================================
PRECEDENCE AND VIEW SPECS
Deeply nested view specs (with more directories specified) take
precedence over shallowly nested view specs, and "*" takes
precedence over "...".
Therefore, the following viewspec checks out everything except
the files directly in the root directory.
+...
-*
===================================================================
REORGANIZING TREES USING VIEWSPECS
In some cases, users will want to reorganize their tree to have a
different structure from the one in the repository. Currently,
users can reorganize their trees using switch. I'd like to allow
users to also be able to save and restore this kind of reorganization
using a viewspec.
If you'd like to switch a directory in a viewspec, simply list
the directory you'd like to download right after the directory
in your WC. For example, if you wanted to download
'foo/images/...' and 'bar/images/...' into the directories 'foo'
and 'bar' in your WC, you could do so using the following
viewspec.
+foo/... foo/images/...
+bar/... bar/images/...
If you've already run 'svn switch' on a directory in your
working copy, this switch will show up in the viewspec.
If you checkout a brand new working copy using the same
viewspec, the same switches will be performed.
===================================================================
EDITING VIEWSPECS ON THE FLY
To bring up the viewspec in an editor, simply type svn viewspec. Your
current viewspec will be displayed in your favourite editor.
If you've just performed a regular checkout, your viewspec will show up
as simply "+...". If you've performed a nonrecursive checkout, your
viewspec will show up as "+*".
If you've performed switches on your WC, these operations will also
show up in your viewspec.
Viewspecs are always displayed and parsed relative to the specified
directory. If your viewspec states '+foo/images/...' for the root
directory, the viewspec for 'foo' will be 'images/...', and the
viewspec for 'foo/images' will be '...'. Everything is relative.
===================================================================
QUICK SHORTCUTS FOR EASY EDITING
It's not always convenient to edit viewspecs as a text file. If you
just want to add or remove a file or directory from the viewspec,
you can simply type:
svn viewspec --add foo.txt
svn viewspec --remove bar.txt baz.txt
To add or remove directories, you must either specify the '-N' or
'-R' options, so as to clarify whether you want to recursively
add or remove descendents of these directories. If you do not specify
either of these options, directory targets will be skipped, and a
warning message will be printed.
WARNING:
It's tempting to type svn viewspec --remove * to remove all the files
from the current directory. Note, however, that this a command is
expanded by your shell, so this will only remove files which are
currently in the directory. If you wish to prevent new files from
being added, you must enclose the asterik in single quotes so that it
will not be expanded by your shell.
===================================================================
SEMANTICS OF UPDATE
If you run 'svn up' on a working copy with a viewspec, 'svn up'
honours the viewspec. There are no exceptions to this rule.
'svn up' should not and will not grab files which are not in your
viewspec.
If you want to add or remove a file from your viewspec, use the
viewspec command.
===================================================================
IMPLEMENTATION
This proposal can be implemented in libsvn_wc using the following
steps.
a) The .svn/entries file should have entries for all directories and
files, regardless of whether the checkout is recursive or not.
b) We add a new "recurse-mode" field in .svn/entries.
The following modes are supported for files:
"+": This file is included; it should be updated.
"-": This file is excluded; it should not be updated.
The following modes are supported for directories:
"+...": All children of this directory are included
by default.
"-...": All children of this directory are excluded
by default.
"+*": Immediate children of this directory are included
by default. Subdirectories are included by default.
"-*": Immediate children of this directory are included
by default. Subdirectories are excluded by default.
NOTE:
When traversing the working copy, 'svn' will still need to recurse into
subdirectories which are marked "-...". This marker simply indicates
that child entries are excluded by default. If the directory exists
in your working copy, and a nested file or directory is marked as
included, the most deeply nested marker takes priority.
===================================================================
REFERENCES
[1]: Ben Reser's proposal
http://svn.haxx.se/dev/archive-2005-07/0398.shtml
[2]: Eric Gillespie's proposal
http://svn.haxx.se/dev/archive-2006-06/0769.shtml
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sun Jul 16 10:11:18 2006