Как отредактировать сообщение журнала, уже зафиксированное в Subversion?

Есть ли способ отредактировать сообщение журнала определенной ревизии в Subversion? Я случайно написал неправильное имя файла в моем сообщении о коммите, что может сбить с толку позже.

Я видел, как я могу отредактировать неверное сообщение о коммите в Git?, но решение этого вопроса не похоже на Subversion (согласно svn help commit).

11 ответов

Решение

По сути, вы должны иметь права администратора (прямо или косвенно) для хранилища, чтобы сделать это. Вы можете настроить хранилище так, чтобы все пользователи могли это делать, или изменить сообщение журнала непосредственно на сервере.

Смотрите эту часть FAQ по Subversion (выделено мной):

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

Первый способ заключается в том, чтобы администратор хранилища включил изменение свойств ревизии. Это делается путем создания ловушки, называемой pre-revprop-change (см. Этот раздел в книге Subversion для получения дополнительной информации о том, как это сделать). Хук "pre-revprop-change" имеет доступ к старому сообщению журнала до того, как оно будет изменено, поэтому он может каким-то образом сохранить его (например, отправив электронное письмо). После того, как изменения свойств ревизии включены, вы можете изменить сообщение журнала ревизии, передав ключ --revprop в svn propedit или svn propset, как любой из этих:

$svn propedit -r N --revprop svn:log URL 
$svn propset -r N --revprop svn:log "new log message" URL 

где N - номер редакции, чье лог-сообщение вы хотите изменить, а URL-адрес - местоположение хранилища. Если вы запустите эту команду из рабочей копии, вы можете пропустить URL.

Второй способ изменить сообщение журнала - использовать svnadmin setlog. Это должно быть сделано путем ссылки на местоположение хранилища в файловой системе. Вы не можете изменить удаленный репозиторий с помощью этой команды.

$ svnadmin setlog REPOS_PATH -r N FILE

где REPOS_PATH - местоположение хранилища, N - номер редакции, чье сообщение журнала вы хотите изменить, а FILE - файл, содержащий новое сообщение журнала. Если хук "pre-revprop-change" не установлен (или по какой-то причине вы хотите обойти скрипт хука), вы также можете использовать опцию --bypass-hooks. Однако, если вы решите использовать эту опцию, будьте очень осторожны. Вы можете обойти такие вещи, как уведомления об изменениях по электронной почте или системы резервного копирования, которые отслеживают свойства изменений.

Когда вы запускаете эту команду,

svn propedit svn:log --revprop -r NNN 

и на всякий случай вы видите это сообщение:

Запрос DAV не выполнен; возможно, что ловушка pre-revprop-change хранилища либо не удалась, либо не существует

Это потому, что Subversion не позволяет вам изменять сообщения журнала, потому что они не версионные и будут потеряны навсегда.

Unix-хостинг SVN

Перейдите в каталог hooks на вашем сервере Subversion (замените ~/svn/reponame на каталог вашего репозитория)

cd ~/svn/reponame/hooks

Удалить расширение

mv pre-revprop-change.tmpl pre-revprop-change

Сделать его исполняемым (не могу сделать chmod +x!)

chmod 755 pre-revprop-change

Источник

Windows-хостинг SVN

Файлы шаблонов в каталоге ловушек нельзя использовать, так как они специфичны для Unix. Вам нужно скопировать пакетный файл Windows pre-revprop-change.bat в каталог крюков, например, тот, который представлен здесь.

Вот удобная вариация, о которой я не вижу упоминания в FAQ. Вы можете вернуть текущее сообщение для редактирования, указав текстовый редактор.

svn propedit svn:log --revprop -r N --editor-cmd vim
svnadmin setlog /path/to/repository -r revision_number --bypass-hooks message_file.txt

В Windows, используя клиент Tortoise SVN:

  1. щелкните правой кнопкой мыши в папке вашего проекта и выберите "Показать журнал"
  2. в окне "Сообщения журнала" щелкните правой кнопкой мыши на ревизии и выберите "Редактировать сообщение журнала".

Если это не сработает, возможно, из-за настройки SVN на сервере, прочтите другие ответы здесь.

Мне тоже недавно было поручено это.

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

Посмотрев пару других примеров в Интернете, я взломал это вместе, мы находимся в среде Windows, так что это наше содержание pre-revprop-change.bat:

@ECHO OFF

set repos=%1
set rev=%2
set user=%3
set propname=%4
set action=%5

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Only allow changes to svn:log. The author, date and other revision
:: properties cannot be changed
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
if /I not '%propname%'=='svn:log' goto ERROR_PROPNAME

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Only allow modifications to svn:log (no addition/overwrite or deletion)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
if /I not '%action%'=='M' goto ERROR_ACTION

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Only allow user to modify their own log messages
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set AUTHOR=
for /f "delims=" %%a in ('svnlook author -r %REV% %REPOS%') do @set AUTHOR=%%a

if /I not '%AUTHOR%'=='%user%' goto ERROR_WRONGUSER

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Only allow user to modify log messages from today, old messages locked down
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set DATESTAMP=
for /f "delims=" %%a in ('svnlook date -r %REV% %REPOS%') do @set DATESTAMP=%%a

for /F "tokens=1-2 delims= " %%a in ("%DATESTAMP%") do (
 set DATESTAMPDATE=%%a
 set DATESTAMPTIME=%%b )

:: Expects DATESTAMPDATE in the format: 2012-02-24
for /F "tokens=1-3 delims=-" %%a in ("%DATESTAMPDATE%") do (
 set DATESTAMPYEAR=%%a
 set DATESTAMPMONTH=%%b
 set DATESTAMPDAY=%%c )

:: Expects date in the format: Thu 08/01/2013
for /F "tokens=1-4 delims=/ " %%a in ("%date%") do (
 set YEAR=%%d
 set MONTH=%%b
 set DAY=%%c )

if /I not '%DATESTAMPYEAR%'=='%YEAR%' goto ERROR_MSGTOOOLD
if /I not '%DATESTAMPMONTH%'=='%MONTH%' goto ERROR_MSGTOOOLD
if /I not '%DATESTAMPDAY%'=='%DAY%' goto ERROR_MSGTOOOLD

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Make sure that the new svn:log message contains some text.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set bIsEmpty=true
for /f "tokens=*" %%g in ('find /V ""') do (
 set bIsEmpty=false
)
if '%bIsEmpty%'=='true' goto ERROR_EMPTY

goto :eof

:ERROR_EMPTY
echo Empty svn:log properties are not allowed. >&2
goto ERROR_EXIT

:ERROR_PROPNAME
echo Only changes to svn:log revision properties are allowed. >&2
goto ERROR_EXIT

:ERROR_ACTION
echo Only modifications to svn:log revision properties are allowed. >&2
goto ERROR_EXIT

:ERROR_WRONGUSER
echo You are not allowed to modify other user's log messages. >&2
goto ERROR_EXIT

:ERROR_MSGTOOOLD
echo You are not allowed to modify log messages older than today. >&2
goto ERROR_EXIT

:ERROR_EXIT
exit /b 1 

Редактировать: оригинальная идея для этого пришла из этой темы:

Если вы используете IDE, как Eclipse, вы можете использовать этот простой способ.

Right click on the project -> Team - Show history

В этом right click on the revision id for your commit and select 'Set commit properties',

Вы можете изменить сообщение, как вы хотите, отсюда.

Если ваш репозиторий позволяет устанавливать свойства ревизии с помощью ловушки pre-revprop-change, вы можете изменить сообщения журнала намного проще.

svn propedit --revprop -r 1234 url://to/repository

Или в TortoiseSVN, AnkhSVN и, возможно, во многих других клиентах subversion, щелкнув правой кнопкой мыши на записи журнала и затем "изменить сообщение журнала".

Subversion FAQ покрывает это, но использует кучу запутанных неопределенных терминов, таких как REPOS_PATH не приводя реальных примеров.

Чтобы заставить его работать, может потребоваться несколько попыток, поэтому сохраните обновленное сообщение коммита в файле. В отличие от svn-commit.tmp файлы, Subversion не сохранит ваш набор текста, если возникнет проблема.

В вашем рабочем каталоге запустите

svn propedit -r N --revprop svn:log

редактировать сообщение о коммите. Если это работает, отлично! Но это, вероятно, не будет, потому что svn:log Свойство revision не версионно, и Subversion по умолчанию остановит его перезапись, либо с помощью скрипта ловушки pre-revprop-changeили сообщение об ошибке, что у вас нет такого хука.

Для изменения хуков вам необходим доступ к файловой системе, в которой находится репозиторий. svn info скажет вам корень хранилища. Предположим, это ~/svnrepo,

  1. cd в ~/svnrepo/hooks
  2. Есть ли pre-revprop-change или жеpre-revprop-change.bat скрипт? Если это так, временно закомментируйте ту часть, которая прерывается, если вы пытаетесь изменить svn:log,
  3. В противном случае в Windows создайте пустой файл с именем pre-revprop-change.bat, Вот один из способов сделать это:

    copy con pre-revprop-change.bat
    ^Z
    
  4. В противном случае на Unix запустите

    echo '#!/bin/sh' > pre-revprop-change
    chmod +x pre-revprop-change
    
  5. В рабочей копии запустите svn propedit -r N --revprop svn:log снова

  6. Отмените ваши изменения в ~/svnrepo/hooks/svn-revprop-change(.bat)

Я нашел хорошую реализацию хука pre-rev-prop-change на стороне сервера на svnforum: https://www.svnforum.org/forum/opensource-subversion-forums/scripts-contributions/8571-pre-revprop-change-shell-script-allows-commiters-to-change-own-log-within-x-hours

Он реализует

  • проверка пользователем, то есть только собственные сообщения фиксации можно редактировать.
  • Svn admin override; админ может редактировать что угодно.
  • сравнение отметок времени: редактировать можно только те коммиты, которые моложе определенного времени

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

Моя версия pre-revprop-changeпакетный скрипт с независимым от локали сравнением времени. Здесь я использую вызов PowerShell, который в некоторых случаях вызывает мигание окна и добавляет заметную задержку.

      @ECHO OFF

set reposPath=%1
set rev=%2
set user=%3
set propName=%4
set action=%5

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Only allow changes to svn:log. The author, date and other revision
:: properties cannot be changed
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
if /I not '%propName%'=='svn:log' goto ERROR_PROPNAME

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Only allow modifications to svn:log (no addition/overwrite or deletion)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
if /I not '%action%'=='M' goto ERROR_ACTION

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Only allow user to modify their own log messages
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set author=
for /f "delims=" %%a in ('svnlook author -r %rev% %reposPath%') do set author=%%a

if /I not '%author%'=='%user%' goto ERROR_WRONGUSER

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Only allow user to modify log messages from today, old messages locked down
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set minDate=
set revDate=
set revDateStr=
for /f "delims=" %%a in ('svnlook date -r %rev% %reposPath%') do set revDateStr=%%a

:: Expects revDateStr in the format: 2012-02-24 ...
:: https://svnbook.red-bean.com/en/1.7/svn.ref.svnlook.c.date.html
for /F "tokens=1-3 delims=- " %%a in ("%revDateStr%") do set revDate=%%a%%b%%c
:: Note that PowerShell calls like this can be slow and a window can show up while they run.
for /f %%i in ('"powershell (Get-Date).AddDays(-1).ToString(\"yyyyMMdd\")"') do set minDate=%%i
if "%revDate%" LSS "%minDate%" goto ERROR_MSGTOOOLD

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Make sure that the new svn:log message contains some text.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set bIsEmpty=true
for /f "tokens=*" %%g in ('find /V ""') do set bIsEmpty=false
if '%bIsEmpty%'=='true' goto ERROR_EMPTY

goto :eof

:ERROR_EMPTY
echo Empty svn:log properties are not allowed. >&2
goto ERROR_EXIT

:ERROR_PROPNAME
echo Only changes to svn:log revision properties are allowed. >&2
goto ERROR_EXIT

:ERROR_ACTION
echo Only modifications to svn:log revision properties are allowed. >&2
goto ERROR_EXIT

:ERROR_WRONGUSER
echo You are not allowed to modify other user's log messages. >&2
goto ERROR_EXIT

:ERROR_MSGTOOOLD
echo You are not allowed to modify log messages that are too old (2+ days). >&2
goto ERROR_EXIT

:ERROR_EXIT
exit /b 1

Источники: оригинальная версия скрипта , предыдущий ответ , пример PowerShell

Другие вопросы по тегам