Свойства

Мы уже рассмотрели как Subversion сохраняет и получает разные версии файлов и директорий из хранилища. Целые главы были посвящены этой самой фундаментальной части функциональных возможностей этого инструмента. И если поддержка версионирования этим ограничится, Subversion все равно останется полноценным инструментом с точки зрения управления версиями.

Однако версионирование этим не ограничивается.

Дополнительно к версионированнию директорий и файлов, Subversion предоставляет для каждой версионированной директории и файла интерфейс для добавления, изменения и удаления версионированных метаданных. К этим метаданным мы обращаемся как к свойствам, присоединенным к каждому элементу рабочей копии, которые можно представить в виде таблицы с двумя столбцами, которая сопоставляет имена свойств соответствующим значениям. Вообще, имена и значения свойств могут быть тем, чем вы хотите чтобы они были, за исключением того, что имена должны быть читаемым текстом. И лучшим из всего является то, что они тоже версионированы также как и текстовое содержимое файлов. Можно также просто как и для текстовых изменений изменять, фиксировать и отменять изменения свойств. Отправка и получение измененных свойств происходит точно так же как и обычные фиксации и обновления — для этого нет необходимости менять обычный порядок действий.

Подобные приведенным выше, свойства используются и Subversion. Так же как и произвольные имена свойств и соответствующие им значения, имеются у файлов и директорий, каждая правка может иметь произвольные свойства, присоединенные к ней. С теми же исключениями — читаемое имя и любое бинарное значение. Главное отличие в том, что свойства правок не версионируются. Другими словами, если изменить значение свойства правки или удалить такое свойство, у Subversion нет возможностей для восстановления предыдущего значения.

Subversion has no particular policy regarding the use of properties. It asks only that you not use property names that begin with the prefix svn:. 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 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 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 pre-defined properties, see Subversion-defined properties.

В этом разделе мы рассмотрим полезность — как для пользователя, так и для самой Subversion — поддержки свойств. Вы узнаете о командах svn, относящихся к свойствам и том как модификация свойств влияет на привычный рабочий цикл. Надеемся, вы убедитесь в том, что свойства в Subversion расширяют возможности контроля версий.

Зачем нужны свойства?

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. Some part of the processes around Subversion's usage to which you adhere, or maybe some additional tooling around Subversion that you use, might find utility in having a place close to your versioned data to hang custom metadata about that data.

Скажем, вы хотите разработать веб-сайт, содержащий много цифровых фотографий и показывающий их с подписью и датой. Набор этих фотографий постоянно изменяется и вы захотите по возможности максимально автоматизировать этот сайт. Фотографии могут быть большого размера и как обычно делают на таких сайтах, для своих посетителей вам будет необходимо показывать миниатюры изображений.

Сделать это вы можете с помощью обычных файлов. То есть рядом, в директории, вы можете иметь файлы image123.jpg и image123-thumbnail.jpg. Либо если вам необходимо сохранить то-же имя файла, миниатюры должны будут находиться в отдельной директории, например, так thumbnails/image123.jpg. Подобным-же образом, отдельно от основного графического файла, можно хранить описание и дату. Проблема здесь в том, что дерево файлов будет многократно увеличиваться при каждом добавлении на сайт фотографии.

Представим эту же ситуацию с веб сайтом, но при использовании Subversion-свойств файлов. Допустим, имеется файл image123.jpg и у этого файла установлено свойство caption, datestamp и даже thumbnail. В этом случае рабочая копия выглядит гораздо более управляемо — фактически она будет выглядеть так, как будто она ничего кроме графических файлов не содержит. Однако ваш скрипт автоматизации знает больше. Он знает, что может воспользоваться svn (а еще лучше языковой обвязкой Subversion — см. «Using Languages Other than C and C++») для получения дополнительной, необходимой для показа на сайте информации, не занимаясь чтением индексного файла или играми с путями файлов.

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 a value all passing, that's meaningful information to have.

Использование свойств

Команда svn предоставляет несколько способов добавления или изменения свойств файлов и директорий. Свойства с короткими, читаемыми значениями, наверное проще всего добавить указав имя и значение свойства в командной строке подкоманды propset.

$ svn propset copyright '(c) 2006 Red-Bean Software' calc/button.c
property 'copyright' set on 'calc/button.c'
$

Однако мы уже знаем о гибкости, предлагаемой Subversion для значений свойств. И если вам необходимо иметь многострочное текстовое, или даже бинарное значение свойства, передавать такое значение через командную строку не удобно. Для таких случаев команда propset имеет параметр --file (-F), указывающий имя файла, содержащего новое значение свойства.

$ svn propset license -F /path/to/LICENSE calc/button.c
property 'license' set on 'calc/button.c'
$

Для имен свойств существует ряд ограничений. Имя свойства должно начинаться с буквы, двоеточия (:) или подчеркивания (_); дальше можно использовать цифры, тире (-) и точки (.). [13]

Дополнительно к команде propset, svn имеет команду propedit. Эта команда использует для добавления или изменения свойств указанную программу-редактор (см. «Config»). При выполнении команды, svn вызывает редактор с временным файлом, содержащим текущее значение свойства (или с пустым файлом, если добавляется новое свойство). Затем вы просто меняете в редакторе значение, пока оно не станет таким, каким бы вы хотели его видеть, сохраняете временный файл и выходите из редактора. Если Subversion обнаружит, что вы действительно изменили существующие значение свойства, будет установлено новое значение. Если вы вышли из редактора не внеся изменений, модификации свойства не произойдет.

$ svn propedit copyright calc/button.c  ### exit the editor without changes
No changes to property 'copyright' on 'calc/button.c'
$

Обращаем ваше внимание на то, что как и другие команды svn, команды, относящиеся к свойствам могут применяться к нескольким путям за раз. Это дает возможность одной командой изменять свойства целого набора файлов. Например, можно сделать вот так:

$ 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'
…
$

Все эти добавления и редактирования свойств не очень полезны, если нельзя просто узнать значение свойства. Поэтому для показа сохраненных для файлов и директорий имен и значений свойств, программа svn предлагает две подкоманды. Команда svn proplist перечисляет существующие для указанного пути свойства. После того как вы знаете имя свойства, можно, используя svn propget, запросить его значение. Эта команда выведет на стандартный поток ввода-вывода значение свойства для элемента по указанному пути (или путями) и с указанным именем.

$ svn proplist calc/button.c
Properties on 'calc/button.c':
  copyright
  license
$ svn propget copyright calc/button.c
(c) 2006 Red-Bean Software

Существует даже вариант команды proplist, который перечисляет как имена, так и значения свойств. Просто добавьте параметр --verbose (-v).

$ svn proplist --verbose 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.
…

Последней, относящейся к свойствам подкомандой является propdel. Не смотря на то, что Subversion позволяет сохранять свойства с пустыми значениями, полностью удалить свойство, используя propedit или propset, нельзя. Например, такая команда не даст желаемого эффекта:

$ svn propset license '' calc/button.c
property 'license' set on 'calc/button.c'
$ svn proplist --verbose 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 --verbose calc/button.c
Properties on 'calc/button.c':
  copyright : (c) 2006 Red-Bean Software
$

Помните, мы говорили о неверсионированных свойствах правок? Их то же можно менять с помощью svn. Просто добавьте параметр командной строки --revprop и укажите правку, чье свойство вы хотите изменить. Учитывая глобальность правок, в этом случае не нужно указывать путь, так как вы находитесь в рабочей копии хранилища, в котором вы хотите изменить свойство правки. В противном случае, нужно просто указать интересующий вас в хранилище URL (в том числе, это может быть и корневой URL хранилища). Например, может понадобиться заменить лог-сообщение фиксации в существующей правке. [14]Если текущая рабочая директория является частью рабочей копии хранилища, можно просто выполнить команду svn propset, не указывая целевой путь:

$ 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 affect 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'
$

Обратите внимание на то, что изменение этих неверсионированных свойств должно быть явно разрешено администратором (см. «Hook Scripts»). Учитывая то, что свойства не версионируются, при не аккуратном редактировании, вы рискуете потерять информацию. Для исключения потери информации, администратор хранилища может принять меры предосторожности и по умолчанию, изменение неверсионированных свойств запрещено.

Подсказка

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 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.

Properties and the Subversion Workflow

Теперь, когда вы познакомились со всеми svn командами, имеющими отношение к свойствам, давайте посмотрим как модификация свойств влияет на привычный порядок работы с Subversion. Как мы уже говорили, так же как и содержимое файлов, свойства файлов и директорий версионированы. В результате, Subversion предоставляет те же возможности по слиянию — в случае конфликтных ситуаций — чужих изменений с вашими собственными.

Так же как и в случае с содержимым файлов, изменение свойств является локальной модификацией и становится постоянной при ее фиксации в хранилище с помощью svn commit. Изменение свойств можно легко отменить — команда svn revert восстановит файлы и директории до их первоначального состояния, включая содержимое, свойства и все остальное. Кроме того, интересную информацию о состоянии свойств файлов и директорий можно получить с помощью команд svn status и svn diff.

$ 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

$

Обратите внимание на то, что подкоманда status показывает M не в первой, а во второй колонке. Это потому, что в calc/button.c изменились свойства, а текстовое содержимое нет. Если бы мы изменили и то и другое, в первой колонке то же была бы буква M (см. «svn status»).

Кроме того нужно помнить о нестандартном подходе, используемом Subversion при выводе различий для свойств. Безусловно, можно запустить svn diff перенаправить вывод, для создания работоспособного файла отличий. Программа patch будет просто игнорировать различия свойств — как правило, она игнорирует любой мусор, который не может обработать. К сожалению, это значит, что для полного применения отличий, сгенерированных svn diff, изменения свойств нужно вносить в ручную.

Automatic Property Setting

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, etc. But to get the full benefit of properties, they must be set on the right files and directories. Unfortunately, that can be a step easily forgotten in the routine of things, especially since failing to set a property doesn't usually result in an obvious error condition (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 «File Executability» for more about this property.) Secondly, it runs a very basic heuristic to determine if that file contains human-readable content. If not, Subversion will automatically set 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 «File Content Type».)

Subversion also provides, via its runtime configuration system (see «Параметры времени выполнения»), a more flexible automatic property setting feature which allows you to create mappings of filename patterns to property names and values. Once again, these mappings affect adds and imports, and not only can 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 any time you add JPEG files—ones that 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 «Config» for more about configuring that support.



[13] Если вы знакомы с XML, то синтаксис XML "Name" использует практически тот же ASCII набор.

[14] Исправление в лог сообщениях орфографических, грамматических ошибок, «просто ошибочных» записей, наверно, самые распространенные случаи использования параметра --revprop.