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.
但不仅仅如此。
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.
注意 | |
---|---|
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 第 10 节 “Subversion 属性”.
注意 | |
---|---|
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 第 3 节 “使用 API”) to dig out the extra information that
your site needs to display without having to read an index file or play path
manipulation games.
注意 | |
---|---|
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 allows 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
(.
).[12]
In addition to the propset command, the svn program supplies the propedit command. This command uses the configured editor program (see 第 1.3.2 节 “配置”) 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 $
你需要用子命令 propdel 来删除属性。语法与其它与属性命令相似:
$ 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.[13] 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' $
即使你没有从版本库检出一个工作副本,你仍然可以通过提供版本库根 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 第 4.2 节 “修正提交消息”). 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.
提示 | |
---|---|
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 ___________________________________________________________________ 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. (We cover svn status in 第 4.3.1 节 “查看你的修改概况”).
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, any property modifications will need to be applied by hand.
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 第 4.2 节 “文件的可执行性” 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 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
第 4.1 节 “文件内容类型” later in this
chapter.)
注意 | |
---|---|
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 第 1 节 “运行配置区”), 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 第 1.3.2 节 “配置” for more about configuring
that support.
注意 | |
---|---|
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 第 3.2 节 “实现版本库钩子” for more about hook scripts.) But there's no way to automatically dictate those preferences to Subversion clients beforehand. |