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

550

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

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

Джереми Рутен
источник
26
Я собирался поднять этот вопрос, но потом понял, что уже 4 месяца назад :)
оксайт
6
Если это код, просто сделайте несколько комментариев и сделайте коммит снова с соответствующими комментариями. Если вы согласны с вашими комментариями, отражающими ошибку, это гораздо меньше усилий и гораздо быстрее. Если нет, то решение Камиля Кисиэля - это верный способ сделать это.
Март
Существует отличный pre-revprop-changeсценарий, который позволяет коммитирующему пользователю изменять свой журнал в течение 3 часов после фиксации. Это отличный компромисс между гибкостью / точными журналами и сохранением точности хранилища: wandisco.com/svnforum/threads/…
jwa
если вы не можете изменить файл, но по-прежнему хотите добавить новое сообщение оsvn propset dummyproperty 1 yourfile; svn commit yourfile -m yourmessage
коммите,

Ответы:

457

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

Смотрите эту часть 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. Однако, если вы решите использовать эту опцию, будьте очень осторожны. Вы можете обойти такие вещи, как уведомления об изменениях по электронной почте или системы резервного копирования, которые отслеживают свойства изменений.

Камил Кисиэль
источник
15
По состоянию на 3 февраля 2010 г. URL-адрес: subversion.apache.org/faq.html#change-log-msg
GreenMatt,
1
Вот базовая реализация svnadmin для опции svn-change-commit
albfan
2
Спасибо! Еще пригодится через 6,5 лет после ответа. :-)
Майкл
Метод пропедит более или менее сработал; Тем не менее, я не мог получить изменения журнала, чтобы отразить в обозревателе хранилища. Я мог видеть только обновленный журнал в командной строке SVN в Windows. Я должен был обновить кэш журнала как последний шаг: stackoverflow.com/questions/25750249/…
user_007
89

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

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в каталог ловушек, например, тот, который представлен здесь .

Алекс. С.
источник
1
Почему вы написали в скобках " не могу сделать chmod + x!"?
Апостол
1
Я создал небольшой скрипт, который реализует ту же идею здесь. Blog.mmonem.com/enable-changing-svn-log
mmonem
SVN_EDITOR, VISUAL или EDITOR должны быть установлены перед использованием svn propedit
Gerd
48

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

svn propedit svn:log --revprop -r N --editor-cmd vim
mcqwerty
источник
17
Это требует, чтобы хук был создан - что требует прав администратора. svn: Repository has not been enabled to accept revision propchanges; ask the administrator to create a pre-revprop-change hook
Мэтт
Вот скрипт для включения журнала: blog.mmonem.com/enable-changing-svn-log
mmonem
37
svnadmin setlog /path/to/repository -r revision_number --bypass-hooks message_file.txt
nickf
источник
Я использую Google Code, поэтому не думаю, что смогу сделать это таким образом, но спасибо.
Джереми Рутен
4
это сработало для меня, так как метод propedit не удался с "Репозитарий не был включен для принятия ревизий изменений". Спасибо!
pfctdayelise
1
+1 за непосредственное указание команды :-) apache.org был недоступен, и я не мог перейти по какой-либо ссылке ...
Рафа
Этот ответ заслуживает больше очков! Это лучше, потому что вам не нужно настраивать хук, чтобы использовать его.
Пери Хартман
1
ответ на этот ответ, работал для меня, не устанавливая ловушку, также не изменил ревизию «дата / время» в журнале, только сообщение, которое было именно тем, на что я надеялся.
segFaultCoder
17

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

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

Посмотрев пару других примеров в Интернете, я взломал это вместе, мы находимся в среде 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 

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

Джош Уэтерли
источник
7
По какой-то причине в моей системе (под управлением Server 2012 и VisualSVN) при последней проверке даты if /I not '%DATESTAMPDAY%'=='%DAY%' goto ERROR_MSGTOOOLDмне пришлось переключаться на двойные кавычки вокруг двух переменных. (Вы не поверите, сколько времени понадобилось, чтобы выяснить.) В противном случае я получу такие вещи, как "== '02' в это время неожиданно" (во 2-й день месяца). Мой бат-фу недостаточно силен, чтобы понять, почему это происходит, но если кто-то столкнется со странными проблемами, это может помочь.
Карл Буссема
@CarlBussema: Спасибо за этот лакомый кусочек. Вы только что спасли меня от головной боли.
Даниэль Сзабо,
1
Также обратите внимание, что в приведенном выше сценарии используется американский формат даты «Ожидается дата в формате: чт 08/01/2013» . Так что если вы не используете это, вам нужно изменить эту часть, в моем случае формат был "mm.dd.yy", и без дня недели.
Цитрак
Это крутой вариант этого приятного ответа: stackoverflow.com/questions/6155/…
NateJ
17

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

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

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

Андрей Н.
источник
Спасибо, это было проще для меня, +1. Необходимо иметь разрешения.
theGabyRod
12

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

Right click on the project -> Team - Show history

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

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

mani_nz
источник
По крайней мере в TortoiseSVN попытка изменить свойства фиксации для фиксации в журнале фиксации завершается неудачно с тем же сообщением об ошибке, что и попытка прямого редактирования сообщения журнала.
Кристиан Северин
1
«Запрос DAV не выполнен; возможно, что ловушка pre-revprop-change хранилища либо не удалась, либо отсутствует. Репозиторий не был включен для принятия изменений редакции; попросите администратора создать ловушку pre-revprop-change». Но, как я уже сказал: он использует TortoiseSVN (как не администратор), а не Eclipse. Может быть, Eclipse взломает разрешения SVN для создания этого хука, я не знаю.
Кристиан Северин
Да, может быть. Попробуйте сделать это в затмении.
mani_nz
@ChristianSeverin, я получаю то же сообщение об ошибке при использовании Eclipse. Это, безусловно, исходит от сервера Subversion.
GreenhouseVeg
10

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

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

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

Берт Хуйбен
источник
2
в Subclipse (Eclipse) это «Установить свойства фиксации».
pfctdayelise
2

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)
andrewdotn
источник
0

Я нашел хорошую реализацию ловушки pre-rev-prop-change на стороне сервера в svnforum: https://www.svnforum.org/forum/opensource-subversion-forums/scripts-contributions/8571-pre-revprop-change -оболочка-скрипты позволяют-commiters-к-изменению собственных логарифмическим-в-х часов

Это реализует

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

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

teroi
источник