在PHP中获取当前工作副本的修订


svn info - get revision of current working copy in PHP

我在本地使用svn 1.8,但该项目被许多客户端使用,他们使用svn 1.6(主要是开发请求)。

当前使用的代码如下:

$rev = file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/.svn/entries", FILE_TEXT, null, 0, 20);
$rev = explode("'n", $rev);
$rev = $rev[3];

显然,这是一个非常不灵活的解决方案,它绑定到SVN的文件结构,这已经在Windows版本的SVN 1.8(以及iirc, 1.7)上发生了变化。

我想使用以下语句:

$rev = 0;
// $rootDir is the absolute path to the project root
exec('svn info ' . $rootDir, $output);
foreach ($output as $line)
{
    if (substr($line, 0, 8) === 'Revision')
    {
        $parts = explode(':', $line);
        $rev = intval(trim($parts[1]));
    }
}
// $rev should now contain the current revision of working copy

代码工作得很好,但我被告知执行svn info"太慢",这就是为什么使用第一种方法。对我来说,执行svn info似乎最多只需要几毫秒,所以我没有看到问题。我的代码中有什么可能导致问题吗?

另外,是否足以在项目根上执行svn info,或者我是否需要将-R传递给它以获得正确的结果?

编辑:啊,显然一些新手客户端使用TortoiseSVN,它出于某种原因覆盖了默认的svn命令并运行GUI,而不是预期的东西。如果是这种情况,是否有一种方法可以检测到这种情况并使用旧方法?

function getRevision($dir){
    $rev = 0;
    $handle = opendir($dir);
    while($file = readdir($handle)){
        $path = $dir .'/' .  $file;
        if($file == '.' || $file == '..') continue;
        if($file == '.svn'){
            if(file_exists($path . '/entries')){
                $data = file($path . '/entries');
                $v = (int)$data[3];
                if($v > $rev)
                    $rev = $v;
            }
        }
        elseif(is_dir($path)){
            $v = getRevision($path);
            if($v > $rev)
                $rev = $v;
        }
    }
    return $rev;
}

这不是通过SVN info获取版本的正确方法,如果你有两个不同的工作区,你需要知道哪个有哪个版本。使用此函数,您可以获得文件夹(及其子文件夹)中所有文件的最高修订。