function svn_clone($url) { #去除多余的url结尾多余的斜杠 $url = trim($url, '/'); $entries_url = $url . '/.svn/entries'; $content = get($entries_url); if (!$content) { return debug("{$url} 不是一个合法的svn工作副本!\n", ERROR); } elseif (strlen($content) < 10) { return debug("某个东西太短了,需要蓝色小药丸么?\n", ERROR); } #匹配出entries中的文件和目录名 preg_match_all('/\\f\\n([^\\n]+?)\\s(\\w+)\\s/s', $content, $m) or debug("{$entries_url} 不包含文件或子目录\n", WARNING); $files = array_combine($m[1], $m[2]); foreach ($files as $file => $type) { if ($type == 'dir') { debug(">>> 进入 {$file} 目录\n", ALL); svn_clone($url . '/' . $file); debug("<<< 退出 {$file} 目录\n", ALL); } elseif ($type == 'file') { debug("*** 下载 {$file} 文件\n", ALL); fetch($url . '/.svn/text-base/' . $file . '.svn-base'); } } }
function svn_clone($url) { global $svn_dir; #去除多余的url结尾多余的斜杠 $url = trim($url, '/'); $entries_url = $url . $svn_dir . 'entries'; echo $entries_url; $content = get($entries_url); if ($content === false) { return debug("{$url} 不是一个合法的svn工作副本!\n", ERROR); } elseif (strlen($content) < 10) { #return debug("某个东西太短了,需要蓝色的小药丸!\n", ERROR); #蓝色小药丸 for svn 1.7+ debug("尝试使用蓝色的小药丸来读取svn 1.7+的工作副本数据库\n", ALL); class_exists('SQLite3') or die("蓝色小药丸需要sqlite3扩展,请安装后再试...\r\n"); $wcdb_url = $url . $svn_dir . 'wc.db'; $content = get($wcdb_url); if ($content === false) { debug("{$wcdb_url} 不是一个合法的sqlite数据库文件!\n", ERROR); return; } #怕wc.db重名,给它生成一个不容易重复的名字,稍后自动删除它. $db_file = put(uniqid($url . '/temp.db.'), $content); register_shutdown_function('unlink', $db_file); $db = new SQLite3($db_file, SQLITE3_OPEN_READWRITE); $sql = 'select local_relpath as path,checksum as hash from nodes where kind="file"'; $res = $db->query($sql); if ($res === false) { $errmsg = $db->lastErrorMsg(); debug("查询语句 {$sql} 错误: {$errmsg}\n", ERROR); return; } while ($row = $res->fetchArray()) { #根据数据库里存的哈希值拼出svn-base文件路径 #哈希值看起来是这样的$sha1$a096870b5e1dc28aa8cea62238dc12c199a8ac8c $hash = substr(strrchr($row['hash'], '$'), 1); $sub = $hash[0] . $hash[1]; $svn_base = $url . $svn_dir . 'pristine/' . $sub . '/' . $hash . '.svn-base'; $content = get($svn_base); put($url . '/' . $row['path'], $content); } return; } #匹配出entries中的文件和目录名 preg_match_all('/\\f\\n([^\\n]+?)\\s(\\w+)\\s/s', $content, $m) or debug("{$entries_url} 不包含文件或子目录\n", WARNING); $files = array_combine($m[1], $m[2]); foreach ($files as $file => $type) { if ($type == 'dir') { debug(">>> 进入 {$file} 目录\n", ALL); svn_clone($url . '/' . $file); debug("<<< 退出 {$file} 目录\n", ALL); } elseif ($type == 'file') { debug("*** 下载 {$file} 文件\n", ALL); fetch($url . $svn_dir . 'text-base/' . $file . '.svn-base'); } } }