Repository Dictated Configuration — Part 1 of 3: Inheritable Properties

This article is mirrored with permission from the original location http://blogs.collab.net/subversion/the-road-to-repository-dictated-configuration-day-2-autoprops. Inactive links have been removed or updated.

Author: Paul Burba

Posted: 2013-06-25

This is the first article in a series of three describing the different configuration options that can be set in the repository.

Property Inheritance

Even the most casual user of Subversion is likely familiar with versioned properties.  These name:value pairs of metadata are assigned to files or directories.  Some (those properties whose names begin with “svn:“) are attributed special meaning by, and trigger specific behaviors in, Subversion itself; the rest are open for definition and interpretation by users or third-party Subversion-related tools.

Up through Subversion 1.7, versioned properties typically only applied to the file or directory they were set on.  At most, a property set on a directory might apply to the directory’s immediate children 1.  The svn:ignore property for example, if present on a directory, defines a list of unversioned file patterns (in that same directory) which are ignored by svn status and other subcommands.

From here on out we will simply talk about “properties”, rather than differentiating between versioned and revision properties — So just remember that throughout this series of blogs we are talking about versioned properties! Revision properties have no concept of inheritance.

The newly released Subversion 1.8 introduces the concept of inherited properties.  This new feature is quite transparent and in fact you can go about using properties just as you always have and you might never notice any difference.  This is because there really is no such thing as an “inheritable” property or a “non-inheritable” property — all properties are potentially inheritable!

What is really different in 1.8 is that, given a working copy path (or a URL) Subversion now has a mechanism to find the properties set on that path’s parents.  This works even when the path is a working copy path and the path’s parents are not found within the working copy.  This mechanism manifests itself with the new --show-inherited-props option for the svn proplist and svn propget subcommands.

A quick example will show how this new option works.

Note: In today’s example I’ll use nonsense custom properties. In part two and three we’ll demonstrate some new Subversion reserved properties that actually do real work; right now I just want to demonstrate some new core concepts.

Say our repository has the property foo set on the root of the repository and various subtrees.  We can view all of these properties, their locations, and values with a recursive svn propget on the root of the repository 2:

1.8.0>svn pg foo http://svn.example.com/repos --verbose --recursive
Properties on 'http://svn.example.com/repos':
  foo
    bar
Properties on 'http://svn.example.com/repos/calc':
  foo
    baz
Properties on 'http://svn.example.com/repos/calc/trunk':
  foo
    qux
Properties on 'http://svn.example.com/repos/paint':
  foo
    fum
Properties on 'http://svn.example.com/repos/paint/trunk':
  foo
    zot

Now lets checkout a subtree of the repository, ^/calc/trunk:

1.8.0>svn co http://svn.example.com/repos/calc/trunk calc-trunk-wc
A    calc-trunk-wc\doc
A    calc-trunk-wc\src
A    calc-trunk-wc\doc\INSTALL
A    calc-trunk-wc\FAQ
A    calc-trunk-wc\src\real.c
A    calc-trunk-wc\src\main.c
A    calc-trunk-wc\src\button.c
A    calc-trunk-wc\src\integer.c
A    calc-trunk-wc\Makefile
A    calc-trunk-wc\README
 U   calc-trunk-wc
Checked out revision 478.

Not surprisingly, a recursive propget on the root of the newly checked out working copy shows only the foo property on the working copy path corresponding to ^/calc/trunk:

1.8.0>svn pg foo calc-trunk-wc --verbose --recursive
Properties on 'calc-trunk-wc':
  foo
    qux

The same propget command, but this time with the new --show-inherited-props option, shows the same property on the working copy root path, but also reveals the foo properties on the repository parents of that path:

1.8.0>svn pg foo calc-trunk-wc --verbose --recursive --show-inherited-props
Inherited properties on 'calc-trunk-wc',
from 'http://svn.example.com/repos':
  foo
    bar
Inherited properties on 'calc-trunk-wc',
from 'http://svn.example.com/repos/calc':
  foo
    baz
Properties on 'calc-trunk-wc':
  foo
    qux

The foo properties set on ^/paint and ^/paint/trunk are not shown because those paths are not parents of the working copy.  The svn proplist subcommand also supports the --show-inherited-props option and works in a similar way, except of course that all inherited properties, regardless of name, are revealed.

Building Blocks

So now we have the inverse of a recursive propget/proplist; a way to look ‘up’ the repository tree rather than just ‘down’ it.  What can we do with this new found ability?

Keep in mind that all the Subversion reserved properties that existed prior to 1.8 still only apply to the path they are set on or, at most, that path’s immediate children 3.  The same is likely true of any custom properties you’ve added to your own repository — Old properties don’t suddenly have new reach.

That warning aside, property inheritance becomes very useful in two cases:

The first is with new Subversion reserved properties 4 that take advantage of inheritance to apply a property to all subtrees under the path on which the property is set.  In part 2 of this blog, we’ll see the first of two such properties, svn:auto-props.

The second case is with your own custom tools, scripts, workflows, etc. that rely on versioned properties to drive behavior.  For all of those, now you have a new tool to work with, what you do with it is up to you — I suspect that some of you will come up with clever applications for inheritable properties which we never considered when developing the feature.

Caveats

Before we finish for today, there are a few things to keep in mind regarding property inheritance:

Upgrading Older Working Copies

Recall how, in the example above, svn propget --show-inherited-props calc-trunk-wc revealed both the properties on calc-trunk-wc and those which were set on it’s parents in the repository.  Subversion accomplishes this look-up of inherited properties without contacting the repository 5.  It does this by keeping an inherited property cache in the working copy database for the root of the working copy 6.  This cache is updated whenever the working copy is, i.e. during a checkout, update, or switch.  When you upgrade an older format working copy via the ‘svn upgrade’ command, this cache is created, but not populated.  So be sure to update your working copy after an upgrade.

For example: Oops, this is an older working copy!

>svn pg foo --verbose --show-inherited-props
svn: E155036: Please see the 'svn upgrade' command
svn: E155036: The working copy at 'C:\SVN\calc-trunk-wc'
is too old (format 29) to work with client version '1.8.0 (r1490375)' (expects format 31). You need to upgrade the working copy first.

We’ll upgrade the working copy as per the error message:

>svn upgrade

Now check for inherited props:

>svn pg foo --verbose --show-inherited-props
Properties on '.':
  foo
    qux

Oh, that’s right, the cache needs to be populated via an update!

>svn up
Updating '.':
At revision 478.

Now the inherited properties are found:

>svn pg foo --verbose --show-inherited-props
Inherited properties on '.',
from 'http://svn.example.com/repos':
  foo
    bar
Inherited properties on '.',
from 'http://svn.example.com/repos/calc':
  foo
    baz
Properties on '.':
  foo
    qux

Minimum Requirements

While you obviously need a 1.8 Subversion client, a 1.8 server is optional.  A 1.8 server may provide better performance when populating the inherited properties cache or when using the proplist/propget subcommands against a URL.

Authorization

You can only inherit properties from repository paths which you have read access to.  If you don’t have read access to a given path it will appear to you as if there are no properties to inherit from that path.  There is no warning or error issued in this case.

Inheritance Within the Working Copy

As mentioned above, the inherited property cache only knows what properties the root of the working copy inherits.  This means that local changes and or mixed-revision working copies have no effect on what a given working copy path inherits.  This isn’t the place to go into the full implications of this, but keep this simple rule in mind and you shouldn’t have any surprises: If you are counting on having the most up-to-date value of an inherited property (from the root of the repository for example), be sure the root of your working copy is up-to-date.

Notes

  1. Experienced users might reasonably protest that Subversion already has a property whose affects can reach further than a directory’s immediate children, namely the svn:mergeinfo property. You would of course be quite right, svn:mergeinfo is inheritable, however it is a special case with it’s own well-developed set of rules and can safely be disregarded in this discussion of “generic” inheritable properties.

  2. The --verbose option is used here to provide nicely formatted output.

  3. Once again with the notable exception of svn:mergeinfo.

  4. As of Subversion 1.8.0 the only reserved properties which Subversion interprets as inheritable are svn:auto-props (covered in part 2 of this blog) and svn:global-ignores (covered in part 3). Look for more features to be built with inherited properties in future releases of Subversion (a log message templating mechanism comes to mind). In the meantime feel free to use the feature however you’d like. Any piece of versioned metadata you want to apply to your whole repository (or large subsections thereof) can easily be stored in a property on the root of your repository (or the appropriate subtree).

  5. In general Subversion working copies strive to only contact the repository when absolutely necessary. This preserves the ability to use the working copy when the repository cannot be contacted and all other things being equal, a given operation is likely to be faster if the repository does not need to be contacted.

  6. Any switched paths in your working copy count as separate working copy roots and will have their own caches.

About the author

Paul Burba is a committer on the Apache Software Foundation's Subversion project and has worked on Subversion for the past nine years. He works as a software engineer for Collabnet from his home in New Hampshire and when not coding he can usually be found skiing with his nephews, mountain biking with friends, or traveling with his wife. Some time in the distant past Paul graduated from the University of New Hampshire with a degree in Business. Somewhat more recently he obtained a masters in computer science from Boston University.