We've already covered in detail how Subversion stores and
retrieves various versions of files and directories in its
repository. Whole chapters have been devoted to this most
fundamental piece of functionality provided by the tool. And
if the versioning support stopped there, Subversion would still
be complete from a version control perspective.
But it doesn't stop there.
In addition to versioning your directories and files,
Subversion provides interfaces for adding, modifying, and
removing versioned metadata on each of your versioned
directories and files. We refer to this metadata as
properties, and they can be thought of as
two-column tables that map property names to arbitrary values
attached to each item in your working copy. Generally speaking,
the names and values of the properties can be whatever you want
them to be, with the constraint that the names must be
human-readable text. And the best part about these properties
is that they, too, are versioned, just like the textual contents
of your files. You can modify, commit, and revert property
changes as easily as you can file content changes. And the
sending and receiving of property changes occurs as part of your
typical commit and update operations–you don't have to
change your basic processes to accommodate them.
Note
Subversion has reserved the set of properties whose names
begin with svn: as its own. While there
are only a handful of such properties in use today, you should
avoid creating custom properties for your own needs whose names
begin with this prefix. Otherwise, you run the risk that a
future release of Subversion will grow support for a feature
or behavior driven by a property of the same name but with
perhaps an entirely different interpretation.
Properties show up elsewhere in Subversion, too. Just as
files and directories may have arbitrary property names and
values attached to them, each revision as a whole may have
arbitrary properties attached to it. The same constraints
apply–human-readable names and anything-you-want binary
values. The main difference is that revision properties are not
versioned. In other words, if you change the value of, or
delete, a revision property, there's no way within the scope of
Subversion's functionality to recover the previous value.
Subversion has no particular policy regarding the use of
properties. It asks only that you not use property names that
begin with the prefix svn:. That's the
namespace that it sets aside for its own use. And Subversion
does, in fact, use properties, both the versioned and
unversioned variety. Certain versioned properties have special
meaning or effects when found on files and directories, or house
a particular bit of information about the revisions on which
they are found. Certain revision properties are automatically
attached to revisions by Subversion's commit process, and carry
information about the revision. Most of these properties are
mentioned elsewhere in this or other chapters as part of the
more general topics to which they are related. For an
exhaustive list of Subversion's pre-defined properties, see
the section called “Subversion properties”.
In this section, we will examine the utility–both to
users of Subversion, and to Subversion itself–of property
support. You'll learn about the property-related
svn subcommands, and how property
modifications affect your normal Subversion workflow.
Just as Subversion uses properties to store extra
information about the files, directories, and revisions that
it contains, you might also find properties to be of similar
use. You might find it useful to have a place
close to your versioned data to hang custom metadata about
that data.
Say you wish to design a website that houses many digital
photos, and displays them with captions and a datestamp. Now,
your set of photos is constantly changing, so you'd like to
have as much of this site automated as possible. These photos
can be quite large, so as is common with sites of this nature,
you want to provide smaller thumbnail images to your site
visitors.
Now, you can get this functionality using traditional
files. That is, you can have your
image123.jpg and an
image123-thumbnail.jpg side-by-side in a
directory. Or if you want to keep the filenames the same, you
might have your thumbnails in a different directory, like
thumbnails/image123.jpg. You can also
store your captions and datestamps in a similar fashion, again
separated from the original image file. But the problem here
is that your collection of files grows in multiples with each
new photo added to the site.
Now consider the same website deployed in a way that makes
use of Subversion's file properties. Imagine having a single
image file, image123.jpg, and then
properties set on that file named caption,
datestamp, and even
thumbnail. Now your working copy directory
looks much more manageable–in fact, it looks to the
casual browser like there are nothing but image files in it.
But your automation scripts know better. They know that they
can use svn (or better yet, they can use
the Subversion language bindings–see the section called “Using the APIs”) to dig out the
extra information that your site needs to display without
having to read an index file or play path manipulation
games.
Custom revision properties are also frequently used. One
common such use is a property whose value contains an issue
tracker ID with which the revision is associated, perhaps
because the change made in that revision fixes a bug filed in
the tracker issue with that ID. Other uses include hanging
more friendly names on the revision–it might be hard to
remember that revision 1935 was a fully tested revision. But
if there's, say, a test-results property on
that revision with a value all passing,
that's meaningful information to have.
The svn command affords a few ways to
add or modify file and directory properties. For properties
with short, human-readable values, perhaps the simplest way to
add a new property is to specify the property name and value
on the command line of the propset
subcommand.
$ svn propset copyright '(c) 2006 Red-Bean Software' calc/button.c
property 'copyright' set on 'calc/button.c'
$
But we've been touting the flexibility that Subversion
offers for your property values. And if you are planning to
have a multi-line textual, or even binary, property value, you
probably do not want to supply that value on the command line.
So the propset subcommand takes a
--file (-F) option for specifying the name of
a file which contains the new property value.
$ svn propset license -F /path/to/LICENSE calc/button.c
property 'license' set on 'calc/button.c'
$
There are some restrictions on the names you can use for
properties. A property name must start with a letter, a colon
(:), or an underscore
(_); after that, you can also use digits,
hyphens (-), and periods
(.).
[9]
In addition to the propset command, the
svn program supplies the
propedit command. This command uses the
configured editor program (see the section called “Config”) to add or
modify properties. When you run the command,
svn invokes your editor program on a
temporary file that contains the current value of the property
(or which is empty, if you are adding a new property). Then,
you just modify that value in your editor program until it
represents the new value you wish to store for the property,
save the temporary file, and then exit the editor program. If
Subversion detects that you've actually changed the existing
value of the property, it will accept that as the new property
value. If you exit your editor without making any changes, no
property modification will occur:
$ svn propedit copyright calc/button.c No changes to property 'copyright' on 'calc/button.c'
$
We should note that, as with other svn
subcommands, those related to properties can act on multiple
paths at once. This enables you to modify properties on whole
sets of files with a single command. For example, we could
have done:
$ svn propset copyright '(c) 2006 Red-Bean Software' calc/*
property 'copyright' set on 'calc/Makefile'
property 'copyright' set on 'calc/button.c'
property 'copyright' set on 'calc/integer.c'
…
$
All of this property adding and editing isn't really very
useful if you can't easily get the stored property value. So
the svn program supplies two subcommands
for displaying the names and values of properties stored on
files and directories. The svn proplist
command will list the names of properties that exist on a
path. Once you know the names of the properties on the node,
you can request their values individually using svn
propget. This command will, given a property name and a path (or set of
paths), print the value of the property to
the standard output stream.
$ svn proplist calc/button.c
Properties on 'calc/button.c':
copyright
license
$ svn propget copyright calc/button.c
(c) 2006 Red-Bean Software
There's even a variation of the
proplist command that will list both the
name and value of all of the properties. Simply supply the
--verbose (-v) option.
$ svn proplist -v calc/button.c
Properties on 'calc/button.c':
copyright : (c) 2006 Red-Bean Software
license : ================================================================
Copyright (c) 2006 Red-Bean Software. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions, and the recipe for Fitz's famous
red-beans-and-rice.
…
The last property-related subcommand is
propdel. Since Subversion allows you to
store properties with empty values, you can't remove a
property altogether using propedit or
propset. For example, this command will
not yield the desired effect:
$ svn propset license '' calc/button.c
property 'license' set on 'calc/button.c'
$ svn proplist -v calc/button.c
Properties on 'calc/button.c':
copyright : (c) 2006 Red-Bean Software
license :
$
You need to use the propdel subcommand
to delete properties altogether. The syntax is similar to the
other property commands:
$ svn propdel license calc/button.c
property 'license' deleted from 'calc/button.c'.
$ svn proplist -v calc/button.c
Properties on 'calc/button.c':
copyright : (c) 2006 Red-Bean Software
$
Remember those unversioned revision properties? You can
modify those, too, using the same svn
subcommands that we just described. Simply add the
--revprop command-line parameter, and specify
the revision whose property you wish to modify. Since
revisions are global, you don't need to specify a target path
to these property-related commands so long as you are
positioned in a working copy of the repository whose
revision property you wish to modify. Otherwise, you can
simply provide the URL of any path in the repository of
interest (including the repository's root URL). For example,
you might want to replace the commit log message of an
existing revision.
[10]
If your current working directory is part of a working copy of
your repository, you can simply run the
svn propset command with no target path:
$ svn propset svn:log '* button.c: Fix a compiler warning.' -r11 --revprop
property 'svn:log' set on repository revision '11'
$
But even if you haven't checked out a working copy from
that repository, you can still affect the property change by
providing the repository's root URL:
$ svn propset svn:log '* button.c: Fix a compiler warning.' -r11 --revprop \
http://svn.example.com/repos/project
property 'svn:log' set on repository revision '11'
$
Note that the ability to modify these unversioned
properties must be explicitly added by the repository
administrator (see the section called “Commit Log Message Correction”).
That's because the properties aren't versioned, so you run the risk of
losing information if you aren't careful with your edits.
The repository administrator can set up methods to protect
against this loss, and by default, modification of
unversioned properties is disabled.
Tip
Users should, where possible, use svn
propedit instead of svn
propset. While the end result of the commands is
identical, the former will allow them to see the current
value of the property they are about to change, which helps
them to verify that they are, in fact, making the change
they think they are making. This is especially true when
modifying unversioned revision properties. Also, it is
significantly easier to modify multiline property values in
a text editor than at the command line.
Properties and the Subversion Workflow
Now that you are familiar with all of the
property-related svn subcommands, let's see
how property modifications affect the usual Subversion
workflow. As we mentioned earlier, file and directory
properties are versioned, just like your file contents. As a
result, Subversion provides the same opportunities for
merging–cleanly or with conflicts–someone
else's modifications into your own.
And as with file contents, your property changes are local
modifications, only made permanent when you commit them to the
repository with svn commit. Your property
changes can be easily unmade, too–the svn
revert command will restore your files and
directories to their un-edited states–contents, properties,
and all. Also, you can receive interesting information about
the state of your file and directory properties by using the
svn status and svn diff
commands.
$ svn status calc/button.c
M calc/button.c
$ svn diff calc/button.c
Property changes on: calc/button.c
___________________________________________________________________
Name: copyright
+ (c) 2006 Red-Bean Software
$
Notice how the status subcommand
displays M in the second column instead of
the first. That is because we have modified the properties on
calc/button.c, but not its
textual contents. Had we changed both, we would have seen
M in the first column, too (see the section called “See an overview of your changes”).
You might also have noticed the non-standard way that
Subversion currently displays property differences. You can
still run svn diff and redirect the output
to create a usable patch file. The patch
program will ignore property patches–as a rule, it
ignores any noise it can't understand. This does,
unfortunately, mean that to fully apply a patch generated by
svn diff, any property modifications will
need to be applied by hand.
Automatic Property Setting
Properties are a powerful feature of Subversion, acting as
key components of many Subversion features discussed elsewhere
in this and other chapters–textual diff and merge
support, keyword substitution, newline translation, etc. But
to get the full benefit of properties, they must be set on the
right files and directories. Unfortunately, that
step can be easily forgotten in the routine of things, especially
since failing to set a property doesn't usually result in an
obvious error (at least compared to, say, failing to
add a file to version control). To help your properties get
applied to the places that need them, Subversion provides a
couple of simple but useful features.
Whenever you introduce a file to version control using the
svn add or svn import
commands, Subversion tries to assist by setting some common
file properties automatically. First, on operating systems
whose filesystems support an execute permission bit,
Subversion will automatically set the
svn:executable property on newly added or
imported files whose execute bit is enabled. (See the section called “File Executability” for more
about this property.) Secondly, it runs a very basic
heuristic to determine if that file contains human-readable
content. If not, Subversion will automatically set the
svn:mime-type property on that file to
application/octet-stream (the generic
“this is a collection of bytes” MIME type). Of
course, if Subversion guesses incorrectly, or if you wish to
set the svn:mime-type property to something
more precise–perhaps image/png or
application/x-shockwave-flash–you can
always remove or edit that property. (For more on
Subversion's use of MIME types, see the section called “File Content Type”.)
Subversion also provides, via its runtime configuration
system (see the section called “Runtime Configuration Area”), a more
flexible automatic property setting feature which allows you
to create mappings of filename patterns to property names and
values. Once again, these mappings affect adds and imports,
and can not only override the default MIME type decision made
by Subversion during those operations, but can also set
additional Subversion or custom properties, too. For example,
you might create a mapping that says that any time you add
JPEG files–ones whose names match the pattern
*.jpg–Subversion should automatically
set the svn:mime-type property on those
files to image/jpeg. Or perhaps any files
that match *.cpp should have
svn:eol-style set to
native, and svn:keywords
set to Id. Automatic property support is
perhaps the handiest property-related tool in the Subversion
toolbox. See the section called “Config” for more about
configuring that support.
.
To submit comments, corrections, or other contributions to the text, please visit