我们在 SVN 及其提交后挂钩方面遇到了一个奇怪的问题。
我们有许多网站,这个问题只影响一个网站(至少我发现是这样)。有一个提交后钩子,代码如下:
#!/bin/sh
REPOS="$1"
REV="$2"
WC=/srv/www/sites/sitename
date | tee -a $REPOS/hooks/log.txt
cd $WC && svn update 2>&1 >> $REPOS/hooks/log.txt
echo | tee -a $REPOS/hooks/log.txt
当我提交时,钩子就会运行;目录存在;并且运行该钩子的用户具有访问该目录的正确权限(我已调整了钩子的代码,以将两者都回显到日志文件中进行检查。)
当我 su 到用户并更改到目录时,我可以运行svn update
- 它将使用最新版本进行更新。当我通过钩子执行此操作时,它不会。
我做了一些调查,发现当钩子运行时,它svn update
会被触发;但它对刚刚提交的新修订没有任何作用。我从目标目录中删除了一个文件,并提交了一个更改 - 该文件已恢复,但来自较早的修订 - 事实上,这是我手动更新的最后一个修订。
显然发生了一些奇怪的事情,但我搞不清楚是什么。存储库的配置看起来不错,但我对 SVN 了解不够,无法进一步缩小范围。如果有人能给我一些提示,告诉我下一步该去哪里,我将不胜感激。
编辑
svn info
给我:
URL: file:///srv/svn/repos/sitename/trunk
Repository Root: file:///srv/svn/repos/sitename
Repository UUID: 8f30e7d8-358c-4aa0-ba90-4bb80c6b434e
Revision: 132
Node Kind: directory
Schedule: normal
Last Changed Author: authorname
Last Changed Rev: 132
Last Changed Date: 2013-06-17 09:47:46 -0400 (Mon, 17 Jun 2013)
日志文件的输出没有帮助;当我仅提交文件时,我看到:
Mon Jun 17 10:05:08 EDT 2013
这是最后一次提交的时间。svn update
没有在日志文件中输出任何内容。
我刚刚创建了一个新的修订版本 - 我已将新文件添加到存储库的本地副本,并README
从目标目录中删除。日志文件中显示以下内容:
Mon Jun 17 10:11:44 EDT 2013
Restored 'README'
我刚刚提交的修订是 134。没有新文件的迹象,并svn info
告诉我上次更改的记录仍然是 132。
再次编辑
我已根据要求向钩子添加了一些调试代码:
echo $@ >> /tmp/tempfile;
env | tee -a /tmp/tempfile;
得出:
/srv/svn/repos/sitename 150
OLDPWD=/
PWD=/srv/www/sites/sitename
150 是我刚刚添加的修订。
再次编辑
按照要求。第一个是我做了更改并提交时(没有更新任何内容);第二个是我删除文件后再次提交时(文件已恢复,但来自较早的版本)
/srv/svn/repos/sitename 153
OLDPWD=/
PWD=/srv/www/sites/sitename
/srv/svn/repos/sitename 154
OLDPWD=/
PWD=/srv/www/sites/sitename
再次编辑,再次编辑
我创建了一个新的工作目录,并以 www-data 身份登录。我以同一用户身份进行了初始签出;然后提交。svn update
什么也没做。
我确信这不是一个明显的文件权限错误。钩子肯定在运行命令svn update
,因为当我从工作目录中删除文件并运行提交时,它会恢复我删除的文件。
好像 svn 没有看到新版本。我当前在钩子中使用的命令是:
REPOS="$1"
REV="$2"
WC=/srv/www/sites/sitename
/usr/bin/svn update -r $REV "$WC" 2>&1
$1
是正确的存储库名称。$2
是正确的最新版本号。$WC
是正确的目录。
- 当我提交文件时,钩子运行,但不会更新(即使设置了 -r 标志)。
- 当我
svn commit
以正确的用户身份在正确的目录中运行时,它会正确更新 - 当我从工作目录中删除一个文件并提交时,该文件会被恢复,但是会从最新的修订版本中手动运行。
为了完整性,我也尝试使用旧版本的修订号。当我这样做时/usr/bin/svn update -r 10 "$WC" 2>&1
[大约 140 个修订之前],它没有做出任何更改 - 没有删除任何内容,也没有添加任何内容。
更新第五个
将添加svn update
到 cron 中与通过提交后挂钩启动时完全相同;它将更新到我运行的最后一个版本svn update
,但会忽略较新的修订版本。如果工作目录和最后一个版本之间没有差异,它将不执行任何操作。是的,cron 正在运行。我以正确的用户和 root 身份尝试了此操作,当时有点沮丧。
此外,我刚刚重新创建了存储库和工作目录。我将本地工作目录中的内容添加到新存储库中,其行为完全相同。尽管设置与我今天早上设置的另一个开发站点完全相同。
所以我现在放弃了。尝试正确修复此问题所带来的麻烦远远超过了偶尔手动更新的不便。感谢大家阅读本文并提出建议。
答案1
为什么不每隔几分钟运行一次 cron 作业来更新工作副本呢?它将避免您在执行提交后挂钩时遇到的麻烦,并且它将为开发人员省去每次提交时必须等待 svn 更新完成的麻烦。
答案2
我遇到了同样的问题,以下方法对我有用。
- 我
svn up
在提交后挂钩内添加了对命令的 stderr 的记录:
svn up >> $REV.log 2>>$REV-error.log
- 发现如下错误:
svn: E000022: Error converting entry in directory '<...>' to UTF-8
svn: E000022: Can't convert string from native encoding to 'UTF-8':
svn: E000022: Listok No2.tex
发现应该存在一些与语言环境相关的问题,因为我的默认配置文件和 svn up 中使用的空配置文件中的语言环境可能不同(可能还有 crontab)。
对提交后钩子添加了必要的修复。
LANG=en_US.UTF-8
export LANG
LANG=en_US.UTF-8 svn up >> $REV.log 2>>$REV-error.log
现在它可以工作了。
不确定它是否会对 OP 有所帮助(6 年后),而且问题可能会有所不同,但我相信,当从命令行和 cron 或其他具有空环境的脚本运行后情况有所不同时,通常怀疑与语言环境相关的问题。