3

我正在 Windows 机器上尝试 pre-revprop-change 挂钩脚本,但发现了一个棘手的问题。

我将我的问题提炼为以下场景:

我有C:\csvn\data\repositories\tr1\hooks\pre-revprop-change.bat内容:

D:\svntest\testhook.py %*
exit %ERRORLEVEL%

testhook.py是:

import os, sys

if __name__ == '__main__':
    # sys.stderr.write(sys.version+'\n') # this is OK, tried.
    newtext = sys.stdin.read() # try to read new log message

    sys.stderr.write('newtext is: %s\n'%newtext)

    exit(2)

但是,在做客户端时svn propset svn:log --revprop -r 2 "newtext",我得到了 python 错误:

Traceback (most recent call last):
  File "D:\svntest\testhook.py", line 5, in <module>
    newtext = sys.stdin.read() # try to read new log message
IOError: [Errno 9] Bad file descriptor

这个错误的原因是什么?

似乎pre-revprop-change.bat没有将 STDIN 句柄传递给 py 脚本。是的,我验证了pre-revprop-change.bat 可以从 STDIN 获取文本(根据Read stdin stream in a batch file 中的说明)。

我也尝试直接从命令行运行pre-revprop-change.batsys.stdin.read() ,没问题。

请帮助我。

屏幕截图如下:

在此处输入图像描述

环境:

  • 视窗服务器 2003
  • Collabnet Subversion Edge 2.3(svn 1.7.3 和 Apache 2.2.22)
  • 从 python.org 安装 Python 2.7.1 msi

==============[最新更新]=====================

不好意思说:我应该写在.bat

exit %ERRORLEVEL%

代替

exit /b %ERRORLEVEL%

对于和我一起尝试过的人,请修复它并重试。/b似乎 pre-revprop-change.bat 总是以 0 退出。提示:如果没有,/b直接从 cmd 窗口运行 .bat 会导致 cmd 窗口关闭,所以我们最好尝试使用cmd /c "pre-revprop-change.bat some param".

在下面重现此问题的快速方法

更重要的是,对于那些仍然感兴趣的人,请

那么我的问题将被重现。(要求:svn.exe 1.7 命令行(collabnet 或 TortoiseSVN),并安装 Python 2.7)

如果仍然无法重现错误。我已经准备了一个 VMware 虚拟机来准确地展示这个问题。在http://down.nlscan.com/misc/chj/winxp-svnhook-py-stdin-error.7z下载 VM (链接预计有效期至 2013 年 9 月)。VMware Player 3.0(免费)足以运行该虚拟机。

==============[找到解决方法]===================</p>

@nmenezes 提供的非常好的解决方法,c:\Python27\python.exe D:\svntest\testhook.py %*在 bat 中。

4

2 回答 2

1

SVN 在没有关联控制台的情况下执行脚本。所以你不会在 STDOUT 上看到任何显示。如果脚本返回不同于 0 的错误代码,则发送到 STDERR 的所有内容都会在 SVN 上显示为一条消息。

这种脚本应该在无人值守的情况下运行,它独立于用户的输入或输出。

您可以尝试将属性值作为额外的命令行参数传递。为此,请将您的 .bat 更改为:

@echo off
set /p NEWTEXT=
test.py %* %NEWTEXT%
exit /b %ERRORLEVEL%

和 .py 到:

import os, sys

if __name__ == '__main__':   
    newtext = sys.argv[6]
    sys.stderr.write('newtext is: %s\n'% newtext)
    exit(2)

我将批处理 STDIN 读取到 NEWTEXT 变量,并将其作为额外的命令行参数传递给您的脚本。

此解决方案不适用于多行值。因此,我再次尝试了您的原始解决方案,并且效果很好。

svn propset svn:log --revprop -r 3 -F svn.txt

在这种情况下,属性值是从 svn.txt 文件中读取的,这是一个多行的文本文件。在这种情况下,带有 set /p 的选项不起作用,正如我们在评论中讨论的那样。但原始脚本有效。

有关信息,在命令行上传递了 5 个属性:

1 - 存储库

2 - 修订号

3 - 用户

4 - 属性名称

5 - 操作(在这种情况下为 M)

属性值在批处理脚本的标准输入上传递。

@Chen,我终于下载了图片。当您将挂钩批次更改为:

c:\python27\python.exe d:\svntest\testhook.py %*
exit %ERRORLEVEL%

看来你的XP机器直接执行python的方式配置错误。

于 2012-09-18T09:58:45.713 回答
0

将它接收到的标准输入引导到它调用的脚本中不是由你的批处理文件决定的吗?

供参考: http ://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true

也许你可以在你的脚本调用前加上 > 符号来实现这一点?

> D:\svntest\testhook.py %*
exit /b %ERRORLEVEL%

看起来如果批处理文件可以从标准输入读取,那么 SVN 正在做它应该做的事情,这取决于你的批处理文件是否可以让你调用的附加脚本使用它。

于 2012-09-18T12:35:10.160 回答