• No results found

One of Subversion’s most powerful features is its property system. In addition to storing the history of a file, Subversion also allows you to associate arbitrary metadata with each file, directory, or revision. Properties are keyed with a user-defined name, and can contain any data that you would like to associate. Additionally, Subversion provides several special properties that Subversion clients use in order to provide added functionality to versioned files.

Properties in Subversion come in two forms. Conceptually, both forms of properties are the same, and both are dealt with using nearly identical syntax. The key difference between the two forms lies in how they are versioned, and how those versions are accessed and modified.

The first form is a versioned property, which is applied to a file or directory. These sorts of properties are the most common, dealt with directly on a day-to-day basis, and tend to just be referred to as properties. Changes to versioned properties are stored with new revisions, when a file is committed, just as changes to the contents of a file are.

The second form of property is an unversioned property that is attached to a specific revision, instead of a file in the repository. These properties, which are called revision properties because they are attached to a revision, can be modified, but their history is not stored. If a revision property is modified, its previous state is irretrievably lost. Internally, Subversion uses revision properties to store information such as commit dates and log messages, but users can also store their own properties as revision properties.

6.1

Storing Metadata

Properties are associated with a file or directory by using thesvn propsetcommand. The simplest way to set a property is by passing to thesvn propsetcommand the property key and value, along with the file to set the property on.

$ svn propset property_key "property value" repos/trunk/foo.h

The property key is a string of your choosing, which will be used later for retrieving the associated data from the file. Property keys are handled internally by Subversion as XML, and therefore the property keys themselves are restricted by valid XML NAMES, which is

“svnbook” — 2005/4/14 — 14:55 — page 86 — #107

i i

86 Chapter 6 Using Properties

basically any string that contains letters, digits,.,-, and_. For a more formal definition, see the XML standard, available from the World Wide Web Consortium (www.w3.org).

When choosing property names, it is a good idea to use some sort of naming convention. The naming scheme used by the built-in Subversion properties is to begin each property key withsvn:. This might seem like a good convention to adopt for your own property names, but alas, the colon isn’t really a valid character in property names. It can only be used reliably in thesvn: prefix. It is, however, a sound idea to use prefixes to categorize your properties. You just can’t categorize them with a colon. Instead, I suggest using a period to separate a category prefix from a property name. This allows you to assign properties to different categories, and name them accordingly, making it easy to quickly identify broad purposes for the properties, which makes specific meaning easier to discern and remember. You are also able to selectively search for all of the properties in a given category, using the

svn proplistcommand, as I will discuss later in Section 6.2.1, “Listing Properties.” As an example, let’s say that you use Subversion properties to store automated tests and file ownership information. You can then standardize on two property categories, namedtestandownership. A property containing a unit-testing script could be named

test.unit, and properties containing the file’s author and copyright could be named

ownership.authorandownership.copyright.

Subversion property values can be of any form, either text or binary. If the property is short, it is easy to provide it as a parameter on the command line (remember to enclose it with quotation marks if it has spaces though). If the property is long, or if it is a binary file, entering the property value on the command line is impractical. In that case, you can direct

svn propsetto read the property from a file using the--file(-F) option, which directs Subversion to read the property’s value from a file, as in the following example.

$ svn propset property_key --file ~/property_val.txt repos/trunk/foo.h

6.1.1

Editing Properties

Sometimes, you don’t want to change an entire property, but would rather make a small change to an existing one. In these cases, Subversion provides you with thesvn propedit

command, which opens the current property in the current editor.1 After you have finished editing the property’s value, you can save the file and quit. As soon as you quit, Subversion will apply the modified property value to the file or directory’s property.

Subversion does not require that a property must exist prior to callingsvn propedit. If you have a long property to add to a file or directory, it is often easier to call

svn propeditinstead ofsvn propsetto add the initial property value to the file. All you need to do is just run thepropeditcommand and type in the property to the new document that is opened in the editor. When you’re done, save and quit.

6.1.2

Automatically Setting Properties

If you have a property that needs to be set for every file of a certain type that’s added, it’s almost a guarantee that you will forget at least once if you need to set the property

6.2 Retrieving Metadata 87

manually every time. Fortunately, if the value of the property is static for every file of a certain filename pattern, you can tell Subversion to set the value automatically. All you have to do is set up the Subversion configuration file with the appropriate patterns and values (see Section 7.2.1).

6.1.3

Committing Properties

When you runsvn propsetorsvn propedit, Subversion sets the new property value in the working copy, but does not contact the repository. Instead, the property changes are scheduled to be committed to the repository on the nextsvn commit. You can tell which files and directories will have properties committed on the nextsvn commitby running

svn status. The status command will show all files with modified properties by placing anMin the second column of its output.

When you commit a file or directory property to the repository, it is handled just like file data. It is applied to the new revision, but doesn’t affect any previous revisions.

6.1.4

Storing Revision Properties

Revision properties are stored using the --revprop option to either svn propset or

svn propedit. They must be set on a particular revision, so you also need to use the

--revision(-r) option when setting or editing a revision property. Be careful when us- ingsvn propset, because changes are applied immediately and are not undoable. Any previous data in the revision property will be irretrievably lost. It is almost always bet- ter to usesvn propeditwhen working with revision properties, as it is much harder to accidentally delete important data that way.

As an example, the following command will invoke an editor to edit a property that stores which issue-tracking issue is fixed in the last revision that you committed.

$ svn status --show-updates Status against revision: 2225

$ svn propedit --revprop --revision 2225 issues.fixes

You’ll notice that I didn’t runsvn propeditwith the HEAD revision label, but instead usedsvn status show-updatesto get the number of the HEAD revision. I do that to ensure that I am setting the revision property on the revision that I think I am. If another user were to commit a new revision while I was editing the property, the HEAD would be changed to point to the new head of the repository, which is likely not the revision that I want to edit. It’s always safer to get the revision number and then use that explicitly.

6.2

Retrieving Metadata

Properties are retrieved via thesvn propgetcommand, which gets a keyed property from a file or directory and outputs it. The command takes a property key, and a file to retrieve the property from (which can either be a file in a working copy or a repository URL). It outputs the property’s value, as in the following example.

“svnbook” 2005/4/14 14:55 page 88 #109

i i

88 Chapter 6 Using Properties

$ svn propget ownership.author hello_world.c William Nagel

Subversion also allows you to pass multiple files tosvn propget, in which case it will output the supplied property for each of the given files. To make it easier to differentiate the property values for the multiple files, Subversion will also prepend the name of each file in front of each value.

$ svn propget author *.txt

Cathedral_and_Bazaar.txt - Eric S. Raymond GPL.txt - Richard M. Stallman

When outputting a property value, Subversion adds a newline at the end of the property in order to prettify the output a bit. That and svn propget’s filename prepending on multiple files, however, is undesirable behavior when the property is a binary file that you want to output. In those cases, you can use the--strictoption to turn off both additions. With strict output, thesvn propgetoutput is suitable for redirecting into a file.

$ svn propget --strict advertising.poster MyFlick.mov > poster.jpg

6.2.1

Listing Properties

To retrieve property values, it’s sometimes necessary to first check to see what properties are available. With Subversion, you can list available properties using thesvn proplist

command. When you runsvn proplist, the command will take a list of versioned files and/or directories and output all of the properties that are set for them.

$ svn proplist svc.tex Properties on 'svc.tex':

copyright.author copyright.date copyright.publisher

If you would also like to get the values of all properties associated with a file, you can runsvn proplistin verbose mode with--verbose(-v). To save you from accidentally dumping the entire contents of a binary file to standard out,svn proplistwill not output a binary property value. Instead, it will output???? to let you know that the value is nonASCII.

$ svn proplist --verbose svc.tex Properties on 'svc.tex':

copyright.author : William Nagel copyright.publisher : Prentice Hall img.cover : ????

The defaultsvn proplistbehavior is to work non-recursively. If you would like to see the properties that are set on all of the files inside a directory though, you can turn on recursive listing with the--recursive(-R) option.

6.2 Retrieving Metadata 89

$ svn proplist --recursive trunk/book Properties on 'trunk/book/svc.tex': copyright.author copyright.date img.cover Properties on 'trunk/book/chapter1.tex': copyright.author copyright.date

Sometimes, you need to get the values of several properties from a collection of files. Although Subversion has no built in mechanism for finding such information directly, you can easily get the information you want by using thegrepcommand to filtersvn proplist’s output. For example, say you have a directory full of image files, each with copyright in- formation attached as a set of properties with names startingcopyright. If you would like to output all of the copyright information on all of those files, you could run a command similar to the following.

$ svn proplist --recursive --verbose trunk/images | grep -E '^¬

Properties on|^ copyright' > copyrights.txt

6.2.2

Outputting Multiple Binary Properties

Occasionally, you will need to retrieve the contents of multiple binary properties and put them into distinct files. If there are only a couple of files, it’s easy enough to just run multiplesvn propget’s, and redirect them into their own files. On the other hand, if the number of files is large, individually retrieving them can be impractical. However, by using a looping construct, such as the forloop in the Bourne Again Shell (BASH), you can easily get multiple files. As an example, the following command will take a list of C files and output the Python testing scripts that are embedded in each file as a property named

test.script.

$ for FILE in *.c;

> do svn propget test.script $FILE > ${$FILE/%.c/-test.py}; > done

$ ls

bar.c bar-test.py foo.c foo-test.py

In this example, thefor FILE in *.c;tells BASH that it should loop through every file that ends in a .cand place its name in the variable FILE. It will then run thesvn propgetcommand for that file and redirect the output into a file that has the same base name as the file containing the property, but with the.csuffix replaced by-test.py. As you can see, after the command has run, both of the C files have had a test script extracted.

6.2.3

Getting Revision Properties

Revision properties are retrieved in pretty much the same manner as regular versioned properties. The only difference is that you must explicitly refer to a revision when getting

“svnbook” — 2005/4/14 — 14:55 — page 90 — #111

i i

90 Chapter 6 Using Properties

a revision property, using the--revision(-r) option. As with the property setting com- mands, you also need to tell Subversion that you are referring to a revision property by using the--revpropoption, like in the following example.

$ svn propget --revprop --revision 4356 svn:log

6.3

Built-in Properties

Subversion provides a number of built-in properties that have special meaning to a Sub- version repository or client. The built-in properties are split into two categories: the file properties and the revision properties. The file properties are assigned to specific files or directories and are generally only assigned explicitly by a user—with the exception of the

svn:mime-typeproperty, and thesvn:executableproperty, which can be set automat- ically when a file is added. The revision properties, on the other hand, are all set automat- ically when a revision is committed to the repository, but can be changed later if the need arises. All of the built-in Subversion properties are named with a naming scheme that starts withsvn:.

6.3.1

File Properties

Subversion provides several file properties that you can set for individual files or directories. Internally, these properties are handled the same as every other property, but each has added meaning and is used by Subversion clients to add functionality to the files.