什么是SVN中的pre-revprop-change hook,如何创建它?

181

我想在代码库浏览器中编辑日志注释,但是收到了一个错误消息,指出该代码库不存在“pre-revprop-change”钩子。除了名称有点可怕之外,“pre-revprop-change”钩子是什么,我该如何创建它?


16
现在这个链接是第二个,就在一个指向这个问题的链接之后 :) - ULysses
该链接指向非常过时的SVNBook 1.0。当前版本为1.7和1.8(夜间版):http://svnbook.red-bean.com/en/1.8/。 - bahrep
11个回答

217

针对Windows操作系统,这里有一个示例批处理文件的链接,该文件只允许更改日志信息而不允许更改其他属性:

http://ayria.livejournal.com/33438.html

将下面的代码复制到一个文本文件中,并将其命名为pre-revprop-change.bat,然后保存在您的仓库的\hooks子目录中即可。

@ECHO OFF
:: Set all parameters. Even though most are not used, in case you want to add
:: changes that allow, for example, editing of the author or addition of log messages.
set repository=%1
set revision=%2
set userName=%3
set propertyName=%4
set action=%5

:: Only allow the log message to be changed, but not author, etc.
if /I not "%propertyName%" == "svn:log" goto ERROR_PROPNAME

:: Only allow modification of a log message, not addition or deletion.
if /I not "%action%" == "M" goto ERROR_ACTION

:: Make sure that the new svn:log message is not empty.
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 messages are not allowed. >&2
goto ERROR_EXIT

:ERROR_PROPNAME
echo Only changes to svn:log messages are allowed. >&2
goto ERROR_EXIT

:ERROR_ACTION
echo Only modifications to svn:log revision properties are allowed. >&2
goto ERROR_EXIT

:ERROR_EXIT
exit /b 1

41
可以在那里链接到该版本:https://dev59.com/w3VD5IYBdhLWcg3wWaRh#68850。我一段时间之前编写了这个钩子并在 SVN 论坛上发布了它。我猜我应该在钩子注释中加入一些致谢。 - Philibert Perusse
1
我正在使用VisualSVN 2.0.8和TortoiseSVN 1.6.11与此脚本,它运行得很好。 - Mark Biek
28
您可以通过在 VisualSVN Server 中右键单击您的存储库名称并选择“属性...”来编辑钩子。您将看到一个名为“钩子”的选项卡,在那里您将看到不同类型的可用钩子。选择正确的钩子,单击“编辑”,然后将上面的代码粘贴进去即可。希望这对 VisualSVN 用户有所帮助! - Chuck Le Butt
7
快速而不太正式的方法是在Windows上创建一个名为hooks\pre-revprop-change.bat的空文件。 - Ben Claar
这在VisualSVN 3.5.6和TortoiseSVN 1.9.4中仍然有效。 - Enigma
显示剩余2条评论

53

基本上,这是一个在未版本化属性在存储库上被修改之前启动的脚本,以便您可以更精确地管理存储库上正在发生的情况。

在SVN分发中有不同挂钩的模板,位于/hooks子目录中(*.tmpl),您需要根据您的操作系统进行编辑和重命名才能激活。


2
所有的指令都在钩子模板脚本中。如果您需要用于 svnsync 镜像的钩子,则默认脚本需要更改,因为它只允许更改 svn:log。Svnsync 更改的不止这些,所以我只是在那里放了一个 exit 0,以允许所有属性更改(因为这只是我的镜像)。 - Matt Connolly
然后将其保存为 pre-revprop-change 到同一目录,并使其对 Web 服务器用户(在 Linux 上)可执行。 - Mateng

22

为了允许在Linux中编辑日志注释:

  • 定位到存储库的hooks目录中的pre-revprop-change.tmpl文件。
  • 将该文件复制到同一目录,并将其重命名为pre-revprop-change
  • 为该文件授予执行权限(对于服务器用户,例如www-data)。

编辑:(感谢lindes)

  • 之后,您可能需要编辑脚本以返回0的退出值,以允许您想要进行的编辑类型。

这还不够……仍然需要适当地更改退出值。但是我仍然觉得它很有帮助,因为它指向了正确的查找位置……而其他一些答案则缺乏此类信息,或者给出了针对Windows的特定答案。所以感谢您提供这个。 - lindes
1
我非常确定,在我的Ubuntu Linux版本中,复制并授予权限就足够了。但是我不再确定了。我已相应地编辑了答案。谢谢。 - Alois Heimer
我确定两天前我尝试过这个答案,但是它并没有像现在这样对我起作用,所以我留下了这个评论。不过,在进行了修改之后,这个答案对我来说是有效的。 - lindes

11

这里是一个包含许多常见钩子的堆栈溢出问题链接Common Types of Subversion Hooks,其中包括Windows平台下pre-revprop-change钩子的原始源代码,该内容被转载到此处。

您应该参考那里的内容,因为它们可能随着时间的推移而得到改进。


8

感谢 #patmortech

我添加了你的代码,它可以实现“只有同一用户才能更改他的代码”的功能。

:: Only allow editing of the same user.
for /f "tokens=*" %%a in ( 
'"%VISUALSVN_SERVER%\bin\svnlook.exe" author -r %revision% %repository%') do ( 
set orgAuthor=%%a
)
if /I not "%userName%" == "%orgAuthor%" goto ERROR_SAME_USER

7
钩子脚本的名称并不可怕,只要你能够理解,它就是“预修订属性更改钩子”。简而言之,pre-revprop-change 钩子脚本的目的是控制未版本化(修订)属性的更改,并发送通知(例如,在修订属性更改时发送电子邮件)。
Subversion 中有两种类型的属性:
- 版本化属性(例如 svn:needs-locksvn:mime-type),可以设置在文件和目录上, - 未版本化(修订)属性(例如 svn:logsvn:date),设置在仓库的修订上。
版本化属性具有历史记录,可以被普通用户操纵,他们对仓库具有读/写访问权限。另一方面,非版本化属性没有任何历史记录,主要用于维护。例如,如果您提交一个修订版本,它会立即获得 svn:date,其值为您提交的 UTC 时间,svn:author 的值为您的用户名,svn:log 的值为您的提交日志消息(如果您指定了任何)。
正如我已经说明的那样,pre-revprop-change 钩子脚本的目的是控制修订属性的更改。您不希望每个具有访问仓库权限的人都能够修改所有修订属性,因此默认情况下禁止更改修订属性。要允许用户更改属性,必须创建 pre-revprop-change 钩子。
最简单的钩子可以只包含一行:exit 0。它将允许任何经过身份验证的用户更改任何修订属性,并且不应在真实环境中使用。在 Windows 上,您可以使用批处理脚本或基于 PowerShell 的脚本来在 pre-revprop-change 钩子中实现一些逻辑。
此 PowerShell 脚本仅允许更改 svn:log 属性,并拒绝空日志消息。
# Store hook arguments into variables with mnemonic names
$repos    = $args[0]
$rev      = $args[1]
$user     = $args[2]
$propname = $args[3]
$action   = $args[4]

# Only allow changes to svn:log. The author, date and other revision
# properties cannot be changed
if ($propname -ne "svn:log")
{
  [Console]::Error.WriteLine("Only changes to 'svn:log' revision properties are allowed.")
  exit 1
}

# Only allow modifications to svn:log (no addition/overwrite or deletion)
if ($action -ne "M")
{
  [Console]::Error.WriteLine("Only modifications to 'svn:log' revision properties are allowed.")
  exit 2
}

# Read from the standard input while the first non-white-space characters
$datalines = ($input | where {$_.trim() -ne ""})
if ($datalines.length -lt 25)
{
  # Log message is empty. Show the error.
  [Console]::Error.WriteLine("Empty 'svn:log' properties are not allowed.")
  exit 3
}

exit 0

这个批处理脚本只允许“svnmgr”用户更改版本属性:
IF "%3" == "svnmgr" (goto :label1) else (echo "Only the svnmgr user may change revision properties" >&2 )

exit 1
goto :eof

:label1
exit 0

3
如果您想保存日志消息上的更改,请使用来自@patmortech(https://dev59.com/IHVC5IYBdhLWcg3wvT5a#468475)的批处理脚本,
他从https://dev59.com/w3VD5IYBdhLWcg3wWaRh#68850复制了该脚本,
并在if "%bIsEmpty%" == "true" goto ERROR_EMPTYgoto :eofbefore之间添加以下行:
set outputFile=%repos%\log-change-history.txt

echo User '%user%' changes log message in rev %rev% on %date% %time%.>>%outputFile%
echo ----- Old message: ----->>%outputFile%
svnlook propget --revprop %repos% svn:log -r %rev% >>%outputFile%
echo.>>%outputFile%
echo ----- New message: ----->>%outputFile%
for /f "tokens=*" %%g in ('find /V ""') do (echo %%g >>%outputFile%)
echo ---------->>%outputFile%
echo.>>%outputFile%

它将在服务器上的仓库文件夹中创建一个文本文件log-change-history.txt,并追加每个日志更改通知。

很棒的解决方案。为了与您建议的源兼容,变量名称必须进行调整。要复制的标签名为:eof。 - Bernhard Zechmeister

2
  1. 进入 SVN 仓库目录中的 "hooks" 子文件夹,例如 "D:\SVN\hooks\"
  2. 在那里创建空文件 "pre-revprop-change.bat"
  3. 在文件中写入 "exit 0"(无引号),并保存
  4. 享受吧 :)

(这种解决方案当然有缺陷,因为没有任何检查/禁止。但对于我这种只使用本地仓库的情况来说,它似乎可以工作。)


2
这对我来说在Windows Server上是最容易的操作: 在VisualSVN中,右键单击您的代码库,然后选择属性...,接着选择钩子选项卡。
选择 Pre-revision property change hook,点击编辑
我需要能够更改作者 - 在多人使用的远程计算机上,很容易因为错误而使用别人存储的凭据进行提交。
下面是经过修改的社区wiki脚本:
@ECHO OFF
:: Set all parameters. Even though most are not used, in case you want to add
:: changes that allow, for example, editing of the author or addition of log messages.
set repository=%1
set revision=%2
set userName=%3
set propertyName=%4
set action=%5

:: Only allow the author to be changed, but not message ("svn:log"), etc.
if /I not "%propertyName%" == "svn:author" goto ERROR_PROPNAME

:: Only allow modification of a log message, not addition or deletion.
if /I not "%action%" == "M" goto ERROR_ACTION

:: Make sure that the new svn:log message is not empty.
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:author messages are not allowed. >&2
goto ERROR_EXIT

:ERROR_PROPNAME
echo Only changes to svn:author messages are allowed. >&2
goto ERROR_EXIT

:ERROR_ACTION
echo Only modifications to svn:author revision properties are allowed. >&2
goto ERROR_EXIT

:ERROR_EXIT
exit /b 1

2

对于PC用户: 当我在Windows Server上使用.bat扩展名时,它并没有起作用。正如Django Reinhardt所建议的那样,我使用了VisualSvn,并创建了一个带有.cmd扩展名的钩子。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接