什么是SVN中的pre-revprop-change挂钩,我该如何创建它?

时间:2008-10-13 10:44:49

标签: svn svn-hooks

我想在存储库浏览器中编辑日志注释,并收到一条错误消息,指出存储库中不存在pre-revprop-change挂钩。除了有一个可怕的名字,什么是pre-revprop-change钩子,我该如何创建它?

10 个答案:

答案 0 :(得分:205)

对于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

答案 1 :(得分:51)

基本上它是在存储库中修改unversioned属性之前启动的脚本,这样您就可以更精确地管理存储库中发生的事情。

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

答案 2 :(得分:12)

对于允许编辑日志注释的Linux,

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

已编辑:(感谢lindes)

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

答案 3 :(得分:11)

这是带有许多常见钩子Common Types of Subversion Hooks的堆栈溢出问题的链接,包括此处交叉发布的Windows pre-revprop-change挂钩的原始源。

你应该参考那里,因为它们可能会随着时间的推移而得到改善。

答案 4 :(得分:6)

谢谢#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

答案 5 :(得分:4)

如果您管理解密它,那么钩子脚本的名称就不那么可怕了:它是预修改属性更改挂钩。简而言之,pre-revprop-change钩子脚本的目的是控制未版本化(修订版)属性的更改并发送通知(例如,在更改版本属性时发送电子邮件)。

Subversion中有两种类型的属性:

  • 可在文件和目录上设置的版本化属性(例如svn:needs-locksvn:mime-type
  • 在存储库修订版上设置的无版本(修订版)属性(例如svn:logsvn:date)。

版本化属性具有历史记录,可以由对存储库具有读/写访问权限的普通用户进行操作。另一方面,未版本化的属性没有任何历史记录,主要用于维护目的。例如,如果您提交修订版,则会立即获得svn:date提交的UTC时间,svn:author使用您的用户名,svn:log提交您的提交日志消息(如果您指定了任何内容)。< / p>

正如我已经指出的那样,pre-revprop-change钩子脚本的目的是控制修订属性的更改。您不希望每个有权访问存储库的人都能够修改所有修订版属性,因此默认情况下禁止更改修订版属性。要允许用户更改属性,您必须创建pre-revprop-change hook。

最简单的钩子只能包含一行: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

答案 6 :(得分:2)

对于PC用户: 在Windows Server上使用时,.bat扩展名对我不起作用。我使用VisualSvn作为Django Reinhardt的建议,它创建了一个扩展名为.cmd的钩子。

答案 7 :(得分:1)

如果要保存对日志消息的更改,请使用@patmortech (https://stackoverflow.com/a/468475) 的上述答案中的批处理脚本,
谁复制了https://stackoverflow.com/a/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%

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

答案 8 :(得分:0)

  1. 转到SVN存储库目录,进入子文件夹“ hooks”,例如“ D:\ SVN \ hooks \”
  2. 在那里创建一个空文件“ pre-revprop-change.bat”
  3. 在文件中写入“退出0”(不带“”)并保存
  4. 享受:)

(此解决方案肯定有弊端,因为没有检查/禁止任何操作。但是对于我来说-只有我使用的本地存储库-似乎可行。)

答案 9 :(得分:0)

在Windows Server上,这对我来说最简单: 在VisualSVN中,右键单击您的存储库,然后选择属性... ,然后选择 Hooks 标签。

选择修订前属性更改钩子,然后单击编辑

我需要能够更改作者-它经常发生在多人使用的远程计算机上,这是由于我们错误地使用他人存储的凭据来签入。

这是粘贴的修改后的社区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