Всегда фиксируйте один и тот же файл с помощью SVN

В моем веб-приложении у меня есть файл, содержащий текущий номер версии через $ Rev $. Это работает нормально, за исключением того, что если я не внесу никаких изменений в этот файл, он не будет зафиксирован.

Есть ли способ заставить один файл всегда фиксироваться на сервере SVN?

Я использую TortoiseSVN для Windows, поэтому любой код или пошаговые инструкции будут мне полезны.

Ответов (13)

Решение

Если у вас установлен TortoiseSVN, у вас также есть инструмент SubWCRev. Используйте этот инструмент для получения исправления вместо неправильного использования ключевого слова $ REV $.

  1. создайте файл шаблона, который содержит ваши определения, возможно, что-то вроде

    const long WC_REV = $ WCREV $;

    в файле с именем version.h.tmpl

  2. при каждой сборке вызывайте SubWCRev, чтобы создать «настоящий» файл, который вы можете использовать в своем приложении:

    Путь к SubWCRev \ to \ workingcopy path \ to \ version.h.tmpl path \ to \ version.h

Это создаст файл version.h из version.h.tmpl с текстом $ WCREV $, замененным на ревизию, в которой в настоящее время находится ваша рабочая копия.

В документах для SubWCRev тоже могут помочь.

В зависимости от вашего клиента, некоторые из них предлагают ловушку перед фиксацией, с помощью которой вы можете реализовать что-то, что просто "касается" файла и помечает его как измененный. Если вы используете что-то вроде Visual Studio, вы можете создать задачу пост-сборки, которая «коснется» файла, но вам нужно будет убедиться, что вы выполнили сборку перед фиксацией изменений.

Раньше я делал это вручную. Я бы запустил сценарий, который использовал бы sed для замены комментария текущей меткой времени в моем файле $ Rev $. Таким образом, содержимое файла изменится, и Subversion зафиксирует его.

Чего я не сделал, так это перейти к следующему шагу: использовать перехватчики репозитория Subversion для автоматизации процесса. Проблема в том, что я не уверен, можно ли изменять содержимое файла в хуках. Документация, кажется, предполагает, что вы не можете.

Вместо этого, я полагаю, вам понадобится небольшой скрипт, который вы бы выполнили вместо svn commit команды, которая сначала обновляет метку времени, а затем запускает обычную фиксацию.

Для этого вы можете использовать svn pre-commit-hooks.
Общая идея, которую я имею в виду, - создать такую, которая перед фиксацией будет помещать новый номер ревизии в файл (получить его с помощью svnlook) или, возможно, изменить фиктивное свойство в файле (оно должно измениться, иначе SVN проигнорирует его).

Для получения дополнительной информации о хуках перед фиксацией я нашел эту страницу полезной.

Создание файла не принесет вам никакой пользы. Файл не фиксируется с полной версией внутри, он заменяется только ключевым словом. Если вы посмотрите на файл внутри репозитория, вы увидите это.

Таким образом, вместо этого вам нужно принудительно обновить файл.

Если вы работаете на платформе Windows, вы можете использовать инструмент SubWCRev, поставляемый с TortoiseSVN. Документация здесь .

@gatekiller: Кажется, TortoiseSVN поддерживает перехватчики на стороне клиента .

@gradonmantank: Потому что он хочет, чтобы этот файл был обновлен до последнего номера ревизии. Вы полностью прочитали его вопрос?

Хук предварительной фиксации может сработать.

Это отлично работает, за исключением того, что если я не внесу никаких изменений в этот файл, он не будет зафиксирован.

Если файл никогда не меняется, зачем вам его фиксировать каждый раз?

[EDIT] @Sean = Я понимаю, что он пытается сделать, но если файл никогда не обновляется с помощью ловушки или какого-либо другого процесса и, следовательно, никогда не изменяется, SVN никогда не получит его.

Может ли файл номера версии быть изменен сценарием, который развертывает ваш веб-сайт из SVN на веб-сервер?

Не уверен насчет Windows, но используя bash-скрипт, я бы сделал что-то вроде ..

$ version=$(svnversion)
$ svn export . /tmp/staging/
Export complete.
$ echo "Revision: ${version}" > /tmp/staging/version.txt

Тогда /tmp/staging/version.txt будет содержать «Revision: 1» (или любой другой номер версии).

Вы, конечно, можете заменить какой-нибудь идентификатор в файле, например $Rev$ (вместо создания, version.txt как в примере выше)

Я предлагаю изменить подход: создание файла каждый раз означает неявное сохранение глобального номера ревизии в этом файле. Там пользователю может потребоваться другое ключевое слово GlobalKey , отсутствие которого объясняется здесь. Я на самом деле не использовал упомянутую svnversion, однако это может привести вас к решению.

По сути, вы хотите, чтобы вывод svnversion команды был в файле.

Такие файлы обычно хранятся вне репозитория и автоматически создаются сценарием сборки. Я предлагаю вам сделать то же самое. Если вы не строите, а только к svn up на стороне сервера, просто позвоните svnversion после svn up или создать скрипт , чтобы сделать оба действия.

С другой стороны, если вам нужно сохранить его в репозитории, svnversion лучшим выбором будет вызов хука перед фиксацией.

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

Что вы, вероятно, упустили, так это то, что вам нужно установить свойство в файле, чтобы ключевое слово Revision обрабатывалось должным образом.

svn propset svn:keywords "Revision" file.txt

Это гарантирует, что всякий раз, когда вы выполняете обновление, флаг $ Rev: xxx $ будет обновлен с учетом текущей версии. Вам не нужно беспокоиться о том, как он привязан к репозиторию.

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

Если вы используете maven, вы можете сделать это с помощью maven-buildnumber-plugin.