如何编辑Subversion中已提交的日志消息?


550

有没有一种方法可以在Subversion中编辑某个修订的日志消息?我不小心在提交消息中输入了错误的文件名,这以后可能会造成混淆。

我已经看到了如何在Git中编辑错误的提交消息?,但对于Subversion而言,该问题的解决方案似乎并不相似(根据svn help commit)。


26
我打算赞成这个问题,但是后来我意识到我已经在4个月前做过了:)
oksayt 2011年

6
如果是代码,则只需添加一些注释,然后使用适当的注释再次提交即可。如果您认为自己的评论反映了错误,那么可以节省很多精力,而且更快。如果不是,那么卡米尔·基西尔(Kamil Kisiel)的解决方案显然是正确的方法。
2012年

有一个出色的pre-revprop-change脚本,允许提交用户在提交后最多3个小时内修改其日志。这是灵活性/准确记录,并保持库的保真度之间是极好的折衷:wandisco.com/svnforum/threads/...
JWA

如果您无法更改文件,但仍想添加新的提交消息,则可以执行svn propset dummyproperty 1 yourfile; svn commit yourfile -m yourmessage
mulllhausen

Answers:


457

本质上,您必须具有(直接或间接)存储库的管理员权限才能执行此操作。您可以配置存储库以允许所有用户执行此操作,也可以直接在服务器上修改日志消息。

请参见本部分中的颠覆常见问题解答(重点煤矿):

日志消息作为附加到每个修订版的属性保留在资源库中。默认情况下,提交日志消息属性(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

1
这是svnadmin选项svn-change-commit
albfan

2
谢谢!答案6.5年后仍然有用。:-)
迈克尔(Michael)

propedit方法或多或少起作用;但是,我无法使日志更改反映在回购浏览器中。我只能在Windows的svn命令行中看到更新的日志。我必须刷新日志高速缓存的最后一步:stackoverflow.com/questions/25750249/...
user_007

89

当您运行此命令时,

svn propedit svn:log --revprop -r NNN 

以防万一您看到此消息:

DAV请求失败;存储库的pre-revprop-change挂钩有可能失败或不存在

这是因为Subversion不允许您修改日志消息,因为它们是未版本化的,并且将永久丢失。

Unix托管的SVN

转到Subversion服务器上的hooks目录(用存储库目录替换〜/ svn / reponame)

cd ~/svn/reponame/hooks

删除扩展名

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

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

chmod 755 pre-revprop-change

资源

Windows托管的SVN

hooks目录中的模板文件不能使用,因为它们是特定于Unix的。您需要将Windows批处理文件复制pre-revprop-change.bat到hooks目录,例如,此处提供的文件。


1
为什么在方括号中写“ 不能 chmod + x!”?
使徒

1
我创建了一个小脚本,在这里实现了相同的想法blog.mmonem.com/enable-changing-svn-log
mmonem 2014年

在使用svn propedit之前,需要设置SVN_EDITOR,VISUAL或EDITOR
Gerd

48

这是我在常见问题解答中没有提到的一些方便的变化。您可以通过指定文本编辑器来返回当前消息以进行编辑。

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

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 2014年

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

我正在使用Google Code,所以我不认为可以这样做,但是谢谢。
杰里米·鲁顿

4
这对我有用,因为propedit方法失败,并显示“尚未启用存储库以接受修订版propchanges”。谢谢!
pfctdayelise,2010年

1
+1是直接提供命令的:-) apache.org目前不可用,我无法遵循任何给定的链接...
Rafa

这个答案值得加分!更好,因为您不必设置挂钩即可使用它。
佩里·哈特曼

1
碰到这个问题,没有设置挂钩就为我工作,也没有更改日志中的“日期/时间”修订,只是消息,这正是我所希望的。
segFaultCoder '16

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'的事件,这一次是意外的”(在每月的第二天)。我的批处理功能不足以知道为什么会发生这种情况,但是如果其他任何人遇到奇怪的问题,它可能会有所帮助。
卡尔·布塞玛

@CarlBussema:感谢您的提示。你救了我一个头疼。
Daniel Szabo 2014年

1
另请注意,上面的脚本使用美国日期格式,“预计格式为:Thu 08/01/2013”。因此,如果您不使用它,则需要修改该部分,在我的情况下,格式为“ mm.dd.yy”,并且没有工作日。
Zitrax 2015年

这是对这个漂亮的答案冷静的变化:stackoverflow.com/questions/6155/...
NateJ

17

在Windows上,使用Tortoise SVN客户端:

  1. 右键单击项目文件夹,然后选择“显示日志”
  2. 在“日志消息”窗口中,右键单击修订,然后选择“编辑日志消息”

如果不起作用,则可能是由于服务器上SVN的设置方式所致,请在此处阅读其他响应。


谢谢,这对我来说是一个更简单的解决方案,+ 1。拥有权限必不可少。
theGabyRod's

12

如果使用的是类似eclipse的IDE,则可以使用这种简单的方法。

Right click on the project -> Team - Show history

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

您可以从此处根据需要修改消息。


至少在TortoiseSVN中,尝试编辑提交日志中的提交的提交属性失败,并带有与尝试直接编辑日志消息相同的错误消息。
Christian Severin 2014年

1
“ DAV请求失败;没有启用存储库的revprop-change挂钩失败或不存在的信息库以接受修订版本更改;请管理员创建一个revprop-change挂钩”。但是正如我所说:这是使用TortoiseSVN(作为非管理员),而不是Eclipse。我不知道,也许Eclipse破解了SVN权限来创建该挂钩。
Christian Severin 2014年

是的,也许。尝试在日食中这样做。
mani_nz 2014年

@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,2010年

2

颠覆常见问题涵盖了这一点,但使用的是一堆混乱的未定义的术语像REPOS_PATH没有给予任何实际的例子。

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

在您的工作目录中,运行

svn propedit -r N --revprop svn:log

编辑提交消息。如果可行,那就太好了!但这可能不会,因为svn:log修订版属性是未版本化的,并且默认情况下Subversion会阻止您使用钩子脚本 pre-revprop-change或没有此钩子的错误消息覆盖它。

要更改挂钩,您需要访问托管该存储库的文件系统。svn info会告诉您存储库根目录。假设是~/svnrepo

  1. cd~/svnrepo/hooks
  2. pre-revprop-changepre-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)的更改

0

我在svnforum上找到了服务器端pre-rev-prop-change钩子的不错实现:https ://www.svnforum.org/forum/opensource-subversion-forums/scripts-contributions/8571-pre-revprop-change 壳脚本允许提交者在x小时内更改自己的日志

它实现

  • 用户检查,即只能编辑自己的提交消息。
  • SVN管理员优先; 管理员可以编辑任何内容。
  • 时间戳比较:只能编辑小于特定时间的提交

从那里抓取并随意编辑。我不想在这里复制它,因为我不是原始作者,并且没有版权声明允许我这样做。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.