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

Posted

技术标签:

【中文标题】如何编辑已在 Subversion 中提交的日志消息?【英文标题】:How to edit log message already committed in Subversion? 【发布时间】:2010-09-23 04:39:21 【问题描述】:

有没有办法在 Subversion 中编辑某个版本的日志消息?我不小心在我的提交消息中写了错误的文件名,这可能会在以后造成混淆。

我见过 How do I edit an incorrect commit message in Git?,但该问题的解决方案似乎与 Subversion 不同(根据 svn help commit)。

【问题讨论】:

我本来打算赞成这个问题,但后来我意识到我在 4 个月前就已经这样做了 :) 如果是代码,只需制作一些 cmets 并使用适当的 cmets 再次提交。如果您对您的 cmets 反映错误感到满意,那么它的工作量会少得多,而且速度会快得多。如果不是,Kamil Kisiel 的解决方案显然是正确的方法。 有一个出色的 pre-revprop-change 脚本,允许提交用户在提交后最多 3 小时内修改他们的日志。这是灵活性/准确日志和维护存储库保真度之间的完美折衷:wandisco.com/svnforum/threads/… 如果你can't change the file but still want to add a new commit message,那么你可以svn propset dummyproperty 1 yourfile; svn commit yourfile -m yourmessage 【参考方案1】:

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

参见Subversion FAQ 中的this part(重点是我的):

日志消息保存在 存储库作为附加到的属性 每次修订。 默认情况下,日志 消息属性 (svn:log) 不能 提交后进行编辑。那是 因为对修订属性的更改 (其中 svn:log 是其中之一)导致 属性的先前值是 永久丢弃,颠覆 试图阻止你这样做 偶然。然而,有一个 几种让 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 是 存储库的位置。如果你 从工作中运行此命令 复制,你可以省略网址。

改变日志的第二种方式 消息是使用 svnadmin setlog。 这必须通过参考 存储库的位置在 文件系统。您不能修改遥控器 使用此命令的存储库。

$ svnadmin setlog REPOS_PATH -r N FILE

其中 REPOS_PATH 是存储库 位置,N 是修订号 您希望更改谁的日志消息, 并且 FILE 是一个包含新的文件 日志消息。如果 “pre-revprop-change”钩子不在 地方(或者你想绕过钩子 出于某种原因脚本),你也可以 使用 --bypass-hooks 选项。 但是,如果您决定使用此 选项,要非常小心。你可能会 绕过诸如电子邮件之类的东西 更改或备份通知 跟踪修订的系统 属性。

【讨论】:

截至 2010 年 2 月 3 日,URL 为 subversion.apache.org/faq.html#change-log-msg 这里是svnadmin选项svn-change-commit的基本实现 谢谢!答案在 6.5 年后仍然有用。 :-) propedit 方法或多或少有效;但是,我无法让日志更改反映在回购浏览器中。我只能在 Windows 的 svn 命令行中看到更新的日志。作为最后一步,我不得不刷新日志缓存:***.com/questions/25750249/… 不幸的是,我在 2021 年需要这个。仍然准确。感谢分享。【参考方案2】:

当你运行这个命令时,

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

Source

Windows 托管的 SVN

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

【讨论】:

为什么你在括号里写“can not do chmod +x!”? 我创建了一个小脚本,在这里实现相同的想法blog.mmonem.com/enable-changing-svn-log SVN_EDITOR, VISUAL 或 EDITOR 需要在使用 svn propedit 前设置【参考方案3】:

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

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

【讨论】:

它确实需要已创建挂钩 - 这需要管理员权限。 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【参考方案4】:
svnadmin setlog /path/to/repository -r revision_number --bypass-hooks message_file.txt

【讨论】:

我正在使用 Google 代码,所以我认为我不能这样做,但是谢谢。 这对我有用,因为 propedit 方法因“尚未启用存储库以接受修订 propchanges”而失败。谢谢! +1 用于直接发出命令 :-) apache.org 现在已关闭,我无法访问任何给定的链接... 这个答案值得加分!这更好,因为您不必设置挂钩即可使用它。 这个答案的凹凸,在没有设置钩子的情况下为我工作,也没有更改日志中的修订“日期/时间”,只是消息,这正是我所希望的.【参考方案5】:

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

    右键单击您的项目文件夹并选择“显示日志” 在“日志消息”窗口中,右键单击修订并选择“编辑日志消息”

如果它不起作用,可能是因为服务器上的 SVN 设置方式,请在此处阅读其他响应。

【讨论】:

谢谢,这对我来说是一个更简单的解决方案,+1。拥有权限是必不可少的。【参考方案6】:

我最近也接到了这个任务。

我们希望允许我们的程序员仅修改他们自己的提交消息,并限制他们被允许这样做的时间。我们决定允许他们修改当天提交的任何日志消息,修复错字等。

在网上看了几个其他的例子后,我一起破解了这个,我们是在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 

编辑:最初的想法来自this thread:

【讨论】:

出于某种原因,在我的系统(运行 Server 2012 和 VisualSVN)上,在最后一个日期检查 if /I not '%DATESTAMPDAY%'=='%DAY%' goto ERROR_MSGTOOOLD 中,我不得不切换到两个变量周围的双引号。 (你不会相信这需要多长时间才能弄清楚。)否则我会得到类似“=='02'此时出乎意料”的东西(在每月的第二天)。我的批处理功能不够强大,无法知道为什么会发生这种情况,但如果其他人遇到奇怪的问题,它可能会有所帮助。 @CarlBussema:谢谢你的花絮。你让我头疼不已。 另请注意,上面的脚本使用美国日期格式,“预计日期格式为:Thu 08/01/2013”​​。因此,如果您不使用该部分,则需要修改该部分,在我的情况下,格式为“mm.dd.yy”,并且没有工作日。 这是这个不错答案的一个很酷的变体:***.com/questions/6155/…【参考方案7】:

如果你使用的是 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 中,尝试编辑提交日志中的提交的提交属性会失败,并显示与尝试直接编辑日志消息相同的错误消息。 "DAV 请求失败;可能是存储库的 pre-revprop-change 挂钩失败或不存在存储库尚未启用以接受修订propchanges;请管理员创建 pre-revprop - 换钩”。但正如我所说:那是使用 TortoiseSVN(作为非管理员),而不是 Eclipse。也许 Eclipse 破解了 SVN 权限来创建那个钩子,我不知道。 是的,也许。尝试在 Eclipse 中执行此操作。 @ChristianSeverin,我在使用 Eclipse 时收到相同的错误消息。它肯定来自 Subversion 服务器。【参考方案8】:

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

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

或者在 TortoiseSVN、AnkhSVN 和可能的许多其他颠覆客户端中,通过右键单击日志条目,然后“更改日志消息”。

【讨论】:

在 Subclipse (Eclipse) 中是“设置提交属性”。【参考方案9】:

Subversion FAQ 涵盖了这一点,但使用了一堆令人困惑的未定义术语,例如 REPOS_PATH,而没有给出任何实际示例。

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

在您的工作目录中,运行

svn propedit -r N --revprop svn:log

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

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

    cd~/svnrepo/hooks 是否有pre-revprop-changepre-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)的更改

【讨论】:

【参考方案10】:

我在 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

它实现了

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

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

【讨论】:

以上是关于如何编辑已在 Subversion 中提交的日志消息?的主要内容,如果未能解决你的问题,请参考以下文章

如何防止没有注释的 Subversion 提交?

允许用户修改Subversion日志的钩子脚本 (linux)

如何获取所有 Subversion 提交作者用户名的列表?

Subversion Hooks 的常见类型

如何在 git-rebase TODO 编辑器会话中查看更多日志行?

如何转换 git 存储库中的大量提交 [重复]