svn - subversion如何编辑一个log消息, 我已经提交?

  显示原文与译文双语对照的内容

是否可以在Subversion中编辑某个版本的日志消息? 我在提交消息中无意中写了错误的文件名,这可能会让人困惑。

我看到了 如何在Git中编辑一个不正确的提交消息? ,但这个问题的解决方案似乎与 Subversion ( 根据 svn help commit ) 不相似。

时间:

基本上你必须有管理员权限( 直接或者间接) 到仓库来执行这里操作。 你可以配置知识库以允许所有用户执行这里操作,也可以直接在服务器上修改日志消息。

请参见 的这一部分 Subversion常见问题 ( 强调挖掘):

日志消息作为附加到每个版本的属性保存在存储库中。 默认情况下,日志消息属性主要为客户 ( svn: 日志) 无法编辑一次。 这是因为修改属性属性( 哪个 svn:log 是一个) 会导致属性值被永久丢弃,Subversion试图防止你意外地执行这里操作。 但是,有几种方法可以使Subversion更改修订属性。

第一种方法是让仓库管理员启用修订属性修改。 这是通过创建一个名为"pre-revprop-change"的钩子完成的( 参见Subversion手册中的这一节获得关于如何执行这里操作的更多细节) 。 "pre-revprop-change"钩子在更改之前可以访问旧的日志消息,因此它可以某种方式保存它。 启用修订属性修改后,可以通过将 --revprop switch 传递到 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 是你想要更改的日志消息,文件是一个包含新日志消息的文件。 如果"pre-revprop-change"钩子没有到位( 或者出于某种原因,你想绕过hook脚本),你也可以使用--bypass-hooks选项。 但是,如果你决定使用这里选项,请非常小心。 你可能绕过了更改的电子邮件通知或者跟踪修订属性的备份系统。

当你运行这里命令时,


svn propedit svn:log --revprop -r NNN

如果你看到这里消息,请执行以下操作:

.dav 请求失败;可能是档案库的 pre-revprop-change 外挂执行失败;或是不存在

操作的原因是Subversion不允许你修改日志消息,因为它们都没有版本并将永久丢失。

转到Subversion服务器的钩子目录( 用你的仓库的目录替换 ~/svn/reponame )


cd ~/svn/reponame/hooks

删除扩展名


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

使它可以执行( 不能执行 chmod +x ) !


chmod 755 pre-revprop-change


svnadmin setlog/path/to/repository -r revision_number --bypass-hooks message_file.txt

下面是一个我在faq中没有提到的方便的变体。 你可以通过指定文本编辑器来返回当前的编辑信息。


svn propedit svn:log --revprop -r N --editor-cmd vim

我最近也是这样做的。

我们想让程序员只修改他们自己的提交消息,并限制他们允许这么做的距离。 我们决定允许他们修改当天提交的任何日志消息,修复错误等。

在网上查看了几个其他示例之后,我将它们合并在一起,我们在一个 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 

编辑:最初的想法来自于这个线程:

如果你的存储库允许通过pre-revprop-change钩子设置修订属性,你可以更容易地更改日志消息。


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

或者在 TortoiseSVN,AnkhSVN和许多其他的subversion客户端右键单击日志条目,然后'更改日志消息'。

如果你使用的是 Eclipse 这样的IDE,你可以使用这种简单的方式。


Right click on the project -> Team - Show history

that right click on the revision id for your commit and select 'Set commit properties'

你可以根据需要修改邮件。

Subversion FAQ 涵盖了这一点,但使用了一系列混乱的未定义术语如 REPOS_PATH,而不给出任何实际示例。

可能需要一些尝试才能使它的正常工作,因此请将更新后的提交消息保存到文件中。 svn-commit.tmp 文件不同,如果有问题,Subversion不会保留你的输入。

在你的工作目录中,运行

svn propedit -r N --revprop svn:log

编辑提交消息。 如果成功,太好了但可能它就不会,因为 svn:log 修订特性是没有版本并且默认情况下无法阻止你改写它,子版本,要么带有钩子脚本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 )
...