有没有办法在 Subversion 中编辑某个版本的日志消息?我不小心在我的提交消息中写了错误的文件名,这可能会在以后造成混淆。
我已经看到如何在 Git 中编辑不正确的提交消息?,但该问题的解决方案似乎与 Subversion 不同(根据svn help commit
)。
有没有办法在 Subversion 中编辑某个版本的日志消息?我不小心在我的提交消息中写了错误的文件名,这可能会在以后造成混淆。
我已经看到如何在 Git 中编辑不正确的提交消息?,但该问题的解决方案似乎与 Subversion 不同(根据svn help commit
)。
本质上,您必须拥有存储库的管理员权限(直接或间接)才能执行此操作。您可以将存储库配置为允许所有用户执行此操作,也可以直接在服务器上修改日志消息。
请参阅Subversion FAQ的这一部分(强调我的):
日志消息作为附加到每个修订版的属性保存在存储库中。默认情况下,日志消息属性(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 不允许您修改日志消息,因为它们是未版本化的并且将永久丢失。
转到您的 Subversion 服务器上的 hooks 目录(将 ~/svn/reponame 替换为您的存储库的目录)
cd ~/svn/reponame/hooks
删除扩展
mv pre-revprop-change.tmpl pre-revprop-change
使其可执行(不能执行 chmod +x!)
chmod 755 pre-revprop-change
不能使用 hooks 目录中的模板文件,因为它们是 Unix 特定的。您需要将 Windows 批处理文件复制pre-revprop-change.bat
到 hooks 目录,例如此处提供的那个。
这是我在常见问题解答中没有提到的一个方便的变体。您可以通过指定文本编辑器返回当前消息进行编辑。
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 客户端:
如果它不起作用,可能是因为服务器上的 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
编辑:最初的想法来自这个线程:
如果您使用的是 Eclipse 之类的 IDE,则可以使用这种简单的方法。
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 svn:log url://to/repository
或者在 TortoiseSVN、AnkhSVN 和许多其他颠覆客户端中,通过右键单击日志条目然后“更改日志消息”。
Subversion FAQ涵盖了这一点,但使用了一堆令人困惑的未定义术语,例如REPOS_PATH
没有给出任何实际示例。
可能需要几次尝试才能使其正常工作,因此请将更新的提交消息保存在文件中。与svn-commit.tmp
文件不同,如果出现问题,Subversion 不会保留您的输入。
在您的工作目录中,运行
svn propedit -r N --revprop svn:log
编辑提交消息。如果这行得通,那就太好了!但它可能不会,因为svn:log
修订属性是未版本化的,并且默认情况下 Subversion 会阻止你覆盖它,无论是使用钩子脚本 pre-revprop-change
,还是你没有这样的钩子的错误消息。
要更改挂钩,您需要访问托管存储库的文件系统。svn info
将告诉您存储库根目录。假设它是~/svnrepo
.
cd
到~/svnrepo/hooks
pre-revprop-change
脚本
pre-revprop-change.bat
?如果是这样,请暂时注释掉如果您尝试更改则中止的部分svn:log
。否则,在 Windows 上,创建一个名为pre-revprop-change.bat
. 这是一种方法:
copy con pre-revprop-change.bat
^Z
否则,在 Unix 上,运行
echo '#!/bin/sh' > pre-revprop-change
chmod +x pre-revprop-change
在工作副本中,svn propedit -r N --revprop svn:log
再次运行
~/svnrepo/hooks/svn-revprop-change
撤消对( .bat
)的更改我在 svnforum 找到了服务器端 pre-rev-prop-change 挂钩的一个很好的实现: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
它实现
从那里抓取并随意编辑。我不想在这里复制它,因为我不是原作者,也没有版权声明允许我这样做。