Я поддерживаю систему сборки в своей компании, которая в настоящее время использует CVS. Эта система сборки используется в нескольких проектах и в нескольких репозиториях CVS.
Каждый раз, когда у нас есть веха выпуска, мы создаем тег. В CVS это просто:
$ cvs tag TAG_NAME
Эта команда работает независимо от модуля или репозитория CVS, если она выполняется в рабочем каталоге CVS.
Однако, чтобы сделать то же самое в Subversion, мне кажется, что сначала мне нужно будет проанализировать вывод svn info
, чтобы получить корень репозитория. Затем я могу создать тег с помощью:
svn cp . $REPO_ROOT/tags/TAG_NAME -m"Created tag TAG_NAME"
Это, конечно, предполагает, что репозиторий svn имеет рекомендуемую структуру каталогов «магистраль, теги, ветки». Так что на всякий случай мне, вероятно, нужно сначала это проверить.
Кажется, нужно проделать много работы, чтобы просто сопоставить номер версии с символическим именем. Есть ли способ лучше?
Хм, с клиентом 1.4 тут вроде не работает. Какую версию svn вы используете?
В отличие от CVS, теги - это больше, чем просто символическое имя в подверсиях, вот в чем суть. Если вы создаете тег, вы фактически создаете ветку. Я рекомендую прочитать это, если вы еще этого не сделали: http://svnbook.red-bean.com/
Я использую svn почти исключительно из командной строки, и мне быстро надоело вводить чудовищные URL. Я наконец написал скрипт svnurl
, который использую из оболочки. Он работает исходя из предположения, что «проект» имеет форму:
.../PROJECTNAME/trunk
tags
branches
Предположим, вы находитесь где-то в рабочей копии PROJECTNAME / branch / foo:
svnurl -tl # gives a list of tags for the current project
svnurl -tlu # the same as full urls
svnurl -t 1.1 # the url for the tag 1.1 of the current project
# analagous functions for branches
svnurl -ru # the url of the "root" of the current working copy
# eg svn://.../PROJECTNAME/branches/foo
svnurl -T # the url of the trunk of the current project
svnurl -pn # the name of the current project, `PROJECTNAME`
# ...
Использование выглядит примерно так:
$ svn cp $(svnurl -T) $(svnurl -t 1.1.1) # tag trunk as 1.1.1
Код некрасивый, но он избавил меня от многих нажатий клавиш и оказался полезным в неожиданном для меня смысле. Я готов поделиться этим, если вам интересно.
Спасибо, мне непременно было бы интересно взглянуть. Я не смогу использовать его напрямую, так как мне нужно поддерживать клиентов Windows, но я хотел бы увидеть, как это работает.
Вы найдете сценарий здесь: [[github.com/bpsm/svnurl/tree/master/svnurl.py visible[svnurl в github]].
Вам не хватает основного принципа Subversion: номер версии является тега. Когда вы «помечаете» его svn cp, вы просто делаете копию этой конкретной ревизии с более длинным именем. И в отличие от тега CVS, вы (или другие разработчики) можете продолжить разработку этого "тега". Это не статическая сущность, как тег CVS (честно говоря, вы можете переместить тег в отдельные файлы CVS, который эффективно "изменяет" его).
Большинство пользователей svn обрабатывают теги так, как их представила CVS. И (по крайней мере, в Apache) вы можете настроить сервер DAV так, чтобы он не разрешал запись / регистрацию в любом каталоге тегов. Я не пробовал этого, и это может помешать вам использовать URL-адреса http для создания тегов (вам придется использовать пути к файлам из оболочки на хост-машине). Но для всех практических целей процесс выпуска должен быть больше заинтересован в конкретном номере ревизии, чем в какой-то произвольной текстовой строке. Последний может быть изменен после релиза; первый должен [*] всегда предоставлять вам доступ к одному и тому же набору файлов каждый раз, когда вы его проверяете.
[*] Всегда есть способ поиграться с файлами за кулисами, постфактум ... Раньше я вручную редактировал файлы RCS и CVS с vi, когда мне нужно было исправить комментарий и т. д. Но без серьезных svn- сообразительность, данный номер версии должен быть довольно постоянным.
Я все это понимаю, но это не актуально. Мои клиенты хотят иметь символическое имя тега, а не версию. Это не изменится (я пробовал).
То, как svn обрабатывает теги, глупо. Почему так сложно иметь список кортежей номер версии <-> имя тега в индексированном файле и использовать его в качестве словаря?
согласен с Дамианом. Сам по себе номер ревизии не используется в качестве тега, поскольку это просто номер. Кроме того, знание номера ревизии не поможет вам, если у вас несколько ветвей, поскольку все дерево имеет общие номера ревизий.
Вот как я это реализовал, если кому-то интересно:
<!-- First, we need to get the svn repository root URL by parsing
the output of 'svn info'. -->
<exec executable = "svn" failonerror = "yes">
<arg line = "info"/>
<redirector outputproperty = "svninfo.out" errorproperty = "svninfo.err">
<outputfilterchain>
<linecontains>
<contains value = "Repository Root: "/>
</linecontains>
<tokenfilter>
<replacestring from = "Repository Root: " to = ""/>
</tokenfilter>
</outputfilterchain>
</redirector>
</exec>
<echo level = "verbose" message = "Root from svn info: ${svninfo.out}"/>
<!-- Set the svn.root property from the svn info output, and append
the module prefix if it exists. The module prefix allows multiple
projects to use the same repository root. -->
<condition property = "svn.root" value = "${svninfo.out}/${svn.module.prefix}">
<isset property = "svn.module.prefix"/>
</condition>
<!-- Note that the next line will have no effect if the property was
set in the condition above, since ant properties are immutable. The
effect is an "else", if the condition above is NOT true. -->
<property name = "svn.root" value = "${svninfo.out}"/>
<echo level = "verbose" message = "Root: ${svn.root}"/>
<!-- Verify the tags directory exists. -->
<exec executable = "svn"
failonerror = "no"
outputproperty = "null"
errorproperty = "svn.ls.error">
<arg line = "ls ${svn.root}/tags"/>
</exec>
<fail>
Cannot find 'tags' subdirectory.
${svn.ls.error}
The subversion repository is expected to have 'trunk', 'branches', and 'tags'
subdirectories. The tag '${tag}' will need to be manually created.
<condition>
<not>
<equals arg1 = "${svn.ls.error}" arg2 = "" trim = "yes"/>
</not>
</condition>
</fail>
<!-- Finally, do the actual tag (copy in subversion). -->
<exec executable = "svn" failonerror = "yes">
<arg line = "cp . ${svn.root}/tags/${tag} -m 'Created tag ${tag}'"/>
</exec>
Я также хочу отметить, что мне известно о различиях между CVS и Subversion в отношении тегов, и что ревизия Subversion для всех практических целей эквивалентна тегу. К сожалению, это не совсем актуально; мои пользователи хотят, чтобы символическое имя состояло из имени модуля и (другого) номера версии.
Если вы добавите --parents в свой svn cp, каталог тегов будет создан, когда он не существует.