Repository Dictated Configuration — Part 1 of 3: Inheritable Properties
Bait-and-switch warning: Despite the title, I won’t talk about repository dictated configuration (RDC) today at any great length. Rather, I’ll talk about the new inherited properties feature, which RDC is built upon, in the hope that it will provide a more complete understanding. In part 2, I’ll move on to the details of RDC proper.
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,
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
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
foo properties set on
^/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.
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,
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.
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:
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
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.
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.
- 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:mergeinfoproperty. You would of course be quite right,
svn:mergeinfois 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. ↩
--verboseoption is used here to provide nicely formatted output. ↩
- Once again with the notable exception of
- 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). ↩
- 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. ↩
- Any switched paths in your working copy count as separate working copy roots and will have their own caches. ↩