svnsync 实现远程 SVN 镜像同步需三步:初始化目标库、执行首次全量同步、配置源库 post-commit 钩子触发增量同步;目标库须仅由 syncuser 写入,且 pre-revprop-change 钩子限制权限,确保历史一致性。

用 svnsync 实现远程 SVN 版本库实时镜像同步,核心是“初始化 + 一次全量同步 + 每次提交后自动触发增量同步”。它不依赖网络共享或文件拷贝,而是通过 Subversion 协议逐修订版本(revision)复制元数据与内容,保证历史一致性。关键在于目标库必须严格受控——仅 svnsync 进程可写,否则会破坏镜像完整性。
准备空镜像库并配置权限控制
在备份服务器上创建全新空库:
svnadmin create /var/svn/mirror_project- 确保该库由 svnserve 或 Apache 托管,能被远程访问(如
file:///var/svn/mirror_project或http://backup-server/svn/mirror_project)
设置专用同步用户(如 syncuser),要求:
- 对源库有 只读权限(用于拉取数据)
- 对镜像库有 读写权限(用于写入)
- 两个库中该用户密码必须一致(简化认证)
编辑镜像库的 hooks/pre-revprop-change 脚本(先复制 pre-revprop-change.tmpl),限制仅 syncuser 可修改修订属性:
#!/bin/sh USER="$3" if [ "$USER" = "syncuser" ]; then exit 0 fi echo "Only syncuser may change revision properties" >&2 exit 1
赋予执行权限:chmod +x pre-revprop-change
初始化并执行首次全量同步
在镜像库所在机器上运行初始化命令(注意 URL 顺序:先目标,再源):
svnsync init file:///var/svn/mirror_project http://source-server/svn/project \ --username syncuser --password yourpass
初始化成功后立即执行首次同步:
svnsync sync file:///var/svn/mirror_project --non-interactive \ --username syncuser --password yourpass
--non-interactive 避免脚本中出现交互提示;若失败,常见原因是锁残留,可用以下命令解锁:
svn propdel svn:sync-lock --revprop -r 0 file:///var/svn/mirror_project
配置源库 post-commit 钩子实现自动增量同步
在源库的 hooks/post-commit 中添加调用语句(Linux 示例):
#!/bin/sh # $1 = repos path, $2 = revision /usr/bin/svnsync sync file:///var/svn/mirror_project \ --non-interactive --username syncuser --password yourpass > /dev/null 2>&1 &
注意几点:
- 末尾加
&让同步异步执行,避免阻塞客户端提交 - 重定向输出防止钩子因 stdout/stderr 未关闭而卡住
- 确保
svnsync命令路径正确(可用which svnsync确认)
Windows 下对应使用 post-commit.bat,内容类似:
@echo off start "" svnsync sync https://backup-server/svn/mirror_project ^ --non-interactive --username syncuser --password yourpass
日常维护与异常处理
同步过程高度敏感,需定期检查:
- 查看镜像库最新版本号是否与源库一致:
svn info file:///var/svn/mirror_project | grep Revision - 若发现跳变或停滞,检查日志、网络连通性、用户权限及磁盘空间
- 源库地址变更时,用
svn propset svn:sync-from-url --revprop -r 0 新URL file:///path更新元数据 - 严禁人工向镜像库提交、修改或回滚——这会直接导致
svnsync sync报错退出
只要钩子正常、网络稳定、权限无误,每次 commit 后几秒内镜像库就会完成增量更新,达到准实时效果。

















