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 contain only ASCII characters. 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]](images/note.png)  | Note | 
|---|---|
| Subversion has reserved the set of properties whose names
        begin with  | 
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 do not use property names that
      begin with the prefix svn: as 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 they
      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 they 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 predefined
      properties, see the section called “Subversion Properties” in
      Chapter 9, Subversion Complete Reference.
| ![[Note]](images/note.png)  | Note | 
|---|---|
| While Subversion automatically attaches 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 web site 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, such as
        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 multiplies with each new
        photo added to the site.
Now consider the same web site deployed in a way that
        makes use of Subversion's file properties.  Imagine having a
        single image file, image123.jpg, with
        properties set on that file that are 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.
| ![[Note]](images/note.png)  | Note | 
|---|---|
| While Subversion places few restrictions on the names and values you use for properties, it has not been designed to optimally carry large property values or large sets of properties on a given file or directory. Subversion commonly holds all the property names and values associated with a single item in memory at the same time, which can cause detrimental performance or failed operations when extremely large property sets are used. | 
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 the value all passing,
        that's meaningful information to have.  And Subversion allow
        you to easily do this via the --with-revprop
        option of the svn commit command:
$ svn commit -m "Fix up the last remaining known regression bug." \
      --with-revprop "test-results=all passing"
Sending        lib/crit_bits.c
Transmitting file data .
Committed revision 912.
$
        The svn program 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 svn 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 multiline textual, or even binary, property value, you
        probably do not want to supply that value on the command line.
        So the svn propset subcommand takes a
        --file (-F) option for
        specifying the name of a file that 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
        (.).[13]
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 that 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 ### exit the editor without changes 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 the following:
$ 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 the value for 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 svn propedit or svn 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.[14]  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 effect 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]](images/tip.png)  | 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 that 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. | 
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.
As with file contents, your property changes are local modifications, made permanent only 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 unedited 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 ___________________________________________________________________ Added: copyright ## -0,0 +1 ## +(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.  (We cover
        svn status in the section called “See an overview of your changes”).
You might also have noticed the nonstandard way that Subversion currently displays property differences. You can still use svn diff and redirect its 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 using patch, any property modifications will need to be applied by hand.
Subversion 1.7 improves this situation in two ways. First, its nonstandard display of property differences is at least machine-readable—an improvement over the display of properties in versions prior to 1.7. But Subversion 1.7 also introduces the svn patch subcommand, designed specifically to handle the additional information which svn diff's output can carry, applying those changes to the Subversion working copy. Of specific relevance to our topic, property differences present in patch files generated by svn diff in Subversion 1.7 or better can be automatically applied to a working copy by the svn patch command. For more about svn patch, see svn patch in Chapter 9, Subversion Complete Reference.
| ![[Note]](images/note.png)  | Note | 
|---|---|
| There's one exception to how property changes are
          reported by svn diff: changes to
          Subversion's special  | 
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, and so on. 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” later in
        this chapter for more about this property.)
Second, Subversion tries to determine the file's MIME
        type.  If you've configured a
        mime-types-files runtime configuration
        parameter, Subversion will try to find a MIME type mapping in
        that file for your file's extension.  If it finds such a
        mapping, it will set your file's
        svn:mime-type property to the MIME type it
        found.  If no mapping file is configured, or no mapping for
        your file's extension could be found, Subversion will fall
        back to heuristic algorithms to determine the file's MIME
        type.  Depending on how it is built, Subversion 1.7 can make
        use of file scanning libraries[15] to detect a file's type based on its
        content.  Failing all else, Subversion will employ its own
        very basic heuristic to determine whether the file contains
        nontextual content.  If so, it automatically sets 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” later in
        this chapter.)
| ![[Note]](images/note.png)  | Note | 
|---|---|
| UTF-16 is commonly used to encode files whose semantic content is textual in nature, but the encoding itself makes heavy use of bytes which are outside the typical ASCII character byte range. As such, Subversion will tend to classify such files as binary files, much to the chagrin of users who desire line-based differencing and merging, keyword substitution, and other behaviors for those files. | 
Subversion also provides, via its runtime configuration
        system (see the section called “Runtime Configuration Area”), a more
        flexible automatic property setting feature that 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 anytime 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.
| ![[Note]](images/note.png)  | Note | 
|---|---|
| Subversion administrators commonly ask if it is possible to configure, on the server side, a set of property definitions which all connecting clients will automatically consider when operating on working copies checked out from that server. Unfortunately, Subversion doesn't offer this feature. Administrators can use hook scripts to validate that the properties added to and modified on files and directories match the administrator's preferred policies, rejecting commits which are non-compliant in this fashion. (See the section called “Implementing Repository Hooks” for more about hook scripts.) But there's no way to automatically dictate those preferences to Subversion clients beforehand. | 
[13] If you're familiar with XML, this is pretty much the ASCII subset of the syntax for XML “Name”.
[14] Fixing spelling errors, grammatical
        gotchas, and “just-plain-wrongness” in commit log
        messages is perhaps the most common use case for
        the --revprop option.
[15] Currently, libmagic is the support library used to accomplish this.