Благодарности: Росту за то, что подтолкнул к написанию данной статьи. Олегу Галабурде – за своевременно поставленные вопросы.
Недавно возник интересный вопрос, как настроить автозамену специальных слов в SVN при коммитах и апдейтах. Поскольку обсуждение вопроса затянулось на 2 часа, решил написать подробную инструкцию, что и как. Однако, поскольку все специальные свойства представляют большой интерес, и могут принести большую пользу при их правильном использовании, то этой статье мы рассмотрим все специальные свойства, а не только свойства авто замены.
Итак, что же такое специальные свойства SVN? Это набор свойств, которые позволяют SVN клиенту определить логику обработки файлов при операциях commit, update и export. Скажите “непонятно” и будете правы, итак приступим к разбору пряников …
Допустим вы Perl программист, и вам необходимо, чтобы в разделе tags всегда лежал бинарный билд программы, который при экспорте или апдейте его на рабочий сервер, был исполнимым (в терминах Linux например имел права на запуск). Как это сделать? есть 2 варианта:
- Экспортировать версию и нужным файлам выдать права на запуск. Хорошо? Хорошо, но не красиво.
- Сказать SVN клиенту, что файл который извлекается, должен быть исполнимым. Вот это уже по-нашему. Итак, что нам нужно сделать? Да ничего особенного, необходимо просто установить свойство svn:executable. Теперь при commit, export, update svn клиент будет автоматически устанавливать флаги исполнимого файла для этого скрипта.
Возникает вопрос, а как правильно установить свойства для файла и можно ли это автоматизировать?
Для того, чтобы установить свойство для файла/папки в svn есть специальная комманда propset. В терминологии клиента коммандной строки установить свойство можно так:
/usr/bin/svn propset svn:executable 1 /you/file/name.pl
В subclipe просто кликните правой клавишей мыши на выбранном файле, войдите в пункт Team, и выберите пункт “Set Property…”, в появившемся окошке вводите имя свойства и его значение. Все …
Теперь к вопросу о автоматизации. Ответ – да, можно. Предположим, вы хотите для всех файлов с расширением .pl установить флаг исполнимости по умолчанию. Нет ничего проще.
1. Открываем конфигурационный файл SVN (в Win32 он находится %USERPROFILE%\Application Data\Subversion\config, в *nix – ${Home}/.subversion/config). В этом файлы, в разделе [miscellany] расскомментируем строчку:
[miscellany]
enable-auto-props = yes
Параметр enable-auto-props указывает SVN клиенту, разрешено ли ему применять свойства для добавляемых в репозиторий файлов.
2. После этого добавьте раздел [auto-props] и определите список типов файлов и автоматически применяемых к ним свойств
Например:
[auto-props]
*.xml = svn:mime-type=text/xml;svn:eol-style=native
*.as = svn:keywords=LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Date Revision Author # добавляем автозамену специальных шаблонов SVN на текущие значения этих свойств в репозитории.
# Linux scripts
*.sh = svn:eol-style=native;svn:executable;svn:mime-type=text/plain
*.m4 = svn:eol-style=native;svn:executable;svn:mime-type=text/plain
*.awk = svn:eol-style=native;svn:executable;svn:mime-type=text/plain
*.pl = svn:executable;svn:eol-style=native;svn:mime-type=text/plain
Все, теперь все новые файлы *.as будут иметь набор автозаменяющихся клачевых слов, а все скрипты Perl будут исполнимыми.
Важно!!! Автоприменение свойств к файлам действует только и исключительно для вновь добавляемых файлов!!! К файлам которые уже находятся под версионным контролем никаких свойств применяться не будет!!! Для того, чтобы применить свойства к существующим в системе контроля версий файлам используйте комманды или опции SVN клиента, которые описаны выше.
Итак с установкой свойств понятно, вернемся к нашим баранам. Приведем список специальных свойств, которые предлагает SVN.
1. svn:executable – используется для контроля прав файла на запуск в операционной системе.
2. svn:mime-type – в основном нужен, чтобы сказать SVN, текстовый это или бинарный ресурс.
3. svn:ignore – содержит набор шаблонов файлов, который будут игнорированы SVN при коммитах и апдейтах.
4. svn:keywords. Собственно то, из-за чего весь сыр-бор. Периодически, осматривая код идеологически подкованных товарищей можно встретить в комментариях информацию следующего вида:
@version $Id: channelintegration.bs.class.php 1217 2008-04-08 13:32:19Z eugene $
информация полезная, но возникает вопрос, как заставить SVN вставлять ее в код и обновлять при изменении этого кода?
Ответ: просто, необходимо настроить параметр svn:keywords для файла и использовать теги ключевых слов в коде.
Всего SVN предоставляет 5 различных ключевых слов (и еще 5-6 алиасов на них), которые несут в себе основную информацию о версии текущего файла. Рассмотрим их:
- Date (алиас LastChangedDate), – описывает дату последнего изменения файла в репозитории, пример: $Date: 2008-04-10 10:41:51 +0300 (Thu, 10 Apr 2008) $
- Revision (алиасы Rev, LastChangedRevision), – отображает ревизию последнего изменения файла в репозитории, пример: @revision SVN: $Revision: 1233 $
- Author (алиас LastChangedBy), – отображает автора последних изменений в репозитории, пример: @changedby $Author: eugene $
- HeadURL (алиас URL), – отображает URL на последнюю версию файла в репозитории, пример: @link $HeadURL: http://www.droopstreet.com/svn/WorldTV.com/trunk/Sources.PHP/svn-test/new-svn-test.php $
- Id – предоставляет комбинированную информацию из предыдущих ключевых слов, пример: @version SVN: $Id: new-svn-test.php 1233 2008-04-10 07:41:51Z eugene $
- Ключевые слова вставляются в код следующим образом: $keyword$.
- Все ключевые слова являются регистрозависимыми, то есть если вы объявили $author$ – такое ключевое слово парсится не будет.
- И самое главное, в код будут вставляться только те ключевые слова, которые определены в свойстве svn:keywords для этого файла, если вы установили это свойство в значение: “Id Date”, то ключевые слова $Author$, “HeadUrl” и т. д. будут проигнорированы.
Пример добавления ключевых слов:
/**
* Some File Description ...
*
* PHP version 5
* @category Business Logic Classes
* @author Eugene A. Kalosha <ekalosha@gmail.com>
* @changedby $Author$
* @version SVN: $Id$
* @revision SVN: $Revision$
* @link $HeadURL$
* @date $Date$
* @copyright (c) 2004-2008 by Eugene A. Kalosha
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @see DLCommom
* @since File available since Release 1.0
*/
После коммита получается следующий результат:
/**
* Some File Description ...
*
* PHP version 5
* @category Business Logic Classes
* @author Eugene A. Kalosha <ekalosha@gmail.com>
* @changedby $Author: eugene $
* @version SVN: $Id: new-svn-test.php 1233 2008-04-10 07:41:51Z eugene $
* @revision SVN: $Revision: 1233 $
* @link $HeadURL: http://www.droopstreet.com/svn/WorldTV.com/trunk/Sources.PHP/svn-test/new-svn-test.php $
* @date $Date: 2008-04-10 10:41:51 +0300 (Thu, 10 Apr 2008) $
* @copyright (c) 2004-2008 by Eugene A. Kalosha
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @see DLCommom
* @since File available since Release 1.0
*/
Спасибо за внимание, вопросы приветствуются.
[...] Советы пользователям svn, SVN auto-props, что это такое и как его готовить [...]
Прикольно, спасибо!
спасибо. попробую использовать.
[...] SVN auto-props, что это такое и как его готовить Недавно возник интересный вопрос, как настроить автозамену специальных слов в SVN при коммитах и апдейтах. Поскольку обсуждение вопроса затянулось на 2 часа, решил написать подробную инструкцию, что и как. Однако, поскольку все специальные свойства представляют большой интерес, и могут принести большую пользу при их правильном использовании, то этой статье мы рассмотрим все специальные свойства, а не только свойства авто замены. [...]
огромадное спасибо!!! И вправду действует!!:)
Замечательно!
Как раз искал способ автоматизировать версионинг файлов
Прошу прощения за археологию. Прочёл вашу заметку в поисках истины)
“$Revision$ – вещь действительно удобная, но подставляет лишь последнюю модифицирующую ревизию для данного файла, а как быть если требуется включить номер последней ревизии хранилища?
P.S. хочу при автосборке в About добавить строку “ProductName ver.XX (build YY)”, где YY – последняя ревизия хранилища.
(С разбором stdout пока не хочу заморачиваться)
Если использование LastChangedRevision не поможет, то боюсь придется заморачиваться с хуками на коммит/апдейт и экспорт в репозитории.
Спасибо за ответ
1. Про хуки думал. На post-commit повесить запись ревизии в некий файл и инклудить его в программе, но тут возникает отдельная проблема: данный файл нельзя заново комитать с машины с SVN сервером (порождает бесконечный цикл), сам же файл должен присутствовать и на машинах разработчиков.
2. На сервере сборки исходники извлекаются скриптами, т.е. можно перенаправить вывод в файл и разобрать последнюю строку вывода (в ней указывается номер ревизии до которой произведена выгрузка), но метод сам по себе тоже не особо удобный, т.к. требует “жесткой” привязки по путям.
Оба варианта, на мой взгляд, реализуемы, но являются несколько неудобными для использования. Пока что прибываю в поиске более элегантного решения)
P.S.: не совсем понял вашу идею об экспорте в репозитории.
Счастья нет. Если вам нужна глобальная ревизия, то вот что по этому поводу говорят сами разработчики svn:
Where’s $GlobalRev$?
New users are often confused by how the $Rev$ keyword works. Since the repository has a single, globally increasing revision number, many people assume that it is this number which is reflected by the $Rev$ keyword’s value. But $Rev$ expands to show the last revision in which the file changed, not the last revision to which it was updated. Understanding this clears the confusion, but frustration often remains—without the support of a Subversion keyword to do so, how can you automatically get the global revision number into your files?
To do this, you need external processing. Subversion ships with a tool called svnversion which was designed for just this purpose. svnversion crawls your working copy and generates as output the revision(s) it finds. You can use this program, plus some additional tooling, to embed that revision information into your files. For more information on svnversion, see the section called “svnversion”.
Спасибо вам!
а есть ли в svn возможность сворачивать ключевые слова, по аналогии с cvs (-kkv -kkvl -kk -ko -kv)
Хотелось бы, что бы файлы в рабочей копии имели краткое описание, а експортнутые – полное.
это имеет смысл при сравнении файлов внешними (да и diff’ом тоже, я так думаю) тулзами, дабы тулзы не спотыкались о различающееся значение кейвордов svn.
Напрямую такой возможности нет. Теоретически можно перехватить хуки на export/checkout/update, но я думаю, что это не очень хорошая идея.