一、背景与痛点
最近公司内部做了一次 SVN 服务器迁移,虽然仓库数据没变,但服务器 IP 变了。为了让部分只读同事能通过 FTP 方便地浏览最新代码(无需安装 SVN 客户端),我在 SVN 服务器上搭建了 FileZilla FTP 服务,并需要一个自动化流程:
- 每天定时从本地 SVN 仓库拉取最新代码
- 导出为纯净的不含
.svn目录的文件夹 - 将导出的目录共享给 FTP 用户(只读权限)
这样既保留了 SVN 版本控制的优势,又让非技术人员能像访问普通文件一样获取最新代码。
二、整体方案
- SVN 服务器:VisualSVN Server 5.4.4,仓库位于
E:\SVN_Server\Repositories\idc - FTP 服务器:FileZilla Server 0.9.60,端口改为
21,共享目录E:\xxksharefiles\xxkfiles\idc - 自动化:Windows 批处理脚本 + 任务计划程序(每天凌晨 2 点执行)
核心思路:
维护一个本地工作副本(Working Copy),每次先 svn update 增量更新,再 svn export 到 FTP 共享目录。这样更新极快(只拉变更),导出也是本地复制,对服务器几乎无压力。
三、脚本详解
以下是实际运行的 svn_update_and_auto_export.bat(已脱敏):
如果执行报错,可删除脚本中的中文注释
@echo off
chcp 65001 > nul
setlocal enabledelayedexpansion
:: 仓库 URL(注意空格用 %20 编码)
set "SVN_REPO=file:///E:/SVN_Server/Repositories/idc"
:: 工作副本目录(存放 .svn 信息)
set WORKING_COPY=E:\SVN_WorkingCopy\idc
:: 最终导出目录(FTP 共享的根目录)
set EXPORT_DIR=E:\xxksharefiles\xxkfiles\idc
:: 日志目录
set LOG_DIR=E:\SVN_Server\Log
set LOG_FILE=%LOG_DIR%\sync_log.txt
:: 创建日志目录
if not exist "%LOG_DIR%" mkdir "%LOG_DIR%"
echo %date% %time% - Starting update and export >> "%LOG_FILE%"
:: 如果工作副本不存在则 checkout,否则 update
if not exist "%WORKING_COPY%\.svn" (
echo First time checkout... >> "%LOG_FILE%"
svn checkout "%SVN_REPO%" "%WORKING_COPY%" >> "%LOG_FILE%" 2>&1
) else (
echo Updating working copy... >> "%LOG_FILE%"
svn update "%WORKING_COPY%" >> "%LOG_FILE%" 2>&1
)
:: 删除旧的导出目录,重新导出(保证纯净)
echo Exporting from working copy... >> "%LOG_FILE%"
if exist "%EXPORT_DIR%" rmdir /s /q "%EXPORT_DIR%"
svn export --force "%WORKING_COPY%" "%EXPORT_DIR%" >> "%LOG_FILE%" 2>&1
echo %date% %time% - Finished >> "%LOG_FILE%"
echo. >> "%LOG_FILE%"
pause
3.1 关键变量说明
| 变量 | 含义 | 示例值 |
|---|---|---|
SVN_REPO | SVN 仓库 URL | file:///E:/SVN_Server/Repositories/idc |
WORKING_COPY | 本地工作副本路径 | E:\SVN_WorkingCopy\idc |
EXPORT_DIR | 导出目录(FTP 共享用) | E:\xxksharefiles\xxkfiles\idc |
3.2 核心命令
svn checkout:首次拉取完整仓库svn update:后续更新(只拉差异)svn export:从工作副本导出纯净代码(不含.svn)
为什么不用
svn export直接从仓库导出?
从工作副本导出是本地复制,几乎零耗时;直接从仓库导出每次都要全量读取仓库文件,仓库大了会很慢。
四、遇到的坑与解决方法
4.1 路径中的空格问题
SVN 的 file:// 协议不支持空格,必须编码为 %20。
❌ 错误:file:///E:\SVN Server\Repositories\idc
✅ 正确:file:///E:/SVN%20Server/Repositories/idc
同时,在批处理中引用带空格的路径时,务必用双引号包裹:"%WORKING_COPY%"。
4.2 中文注释导致“不是内部或外部命令”
如果脚本保存为 UTF-8 编码,:: 后面的中文会被错误解析。
解决:使用 REM 代替 ::,并将脚本保存为 ANSI 编码;或者直接删掉中文注释。
4.3 Access is denied 权限错误
- 确保运行脚本的用户对
WORKING_COPY目录有完全控制权限 - 以管理员身份运行脚本(或任务计划中勾选“使用最高权限运行”)
4.4 % 符号在 URL 中被解释为环境变量
批处理中 % 有特殊含义。要将文字 %20 写入变量,使用 set "VAR=..." 格式(等号后紧跟双引号)可以避免被提前展开。
4.4 win7电脑访问ftp每次跳转浏览器乱码
-
参考链接:FTP解决跳转浏览器的三种方法
-
我是方法三解决的
一般会提示弹窗:
ftp由于代理服务器设置为完全访问,所以文件夹ftp://******将为只读属性。
请尝试以下步骤:
1.先禁用IE高级选项里的FTP文件夹视图,点确定,再重新勾选启用,再点确定;
2.打开任务管理器关闭explorer.exe进程;
五、设置定时任务
- 按
Win + R→taskschd.msc打开任务计划程序 - “创建基本任务” → 名称:“SVN 自动导出到 FTP”
- 触发器:每天,凌晨 2:00
- 操作:启动程序 → 浏览选择
svn_update_and_auto_export.bat - 完成
注意:如果脚本中有
pause,请删除它,否则任务会一直等待。
六、FTP 客户端连接方式
FileZilla Server 端口已改为 21,Windows 客户端连接方法:
使用 Windows 资源管理器
- 打开“此电脑” → 右键“添加一个网络位置”
- 地址填写:
ftp://你的服务器IP:21 - 输入用户名/密码 → 完成
使用 FileZilla Client
- 主机:
你的服务器IP,端口:21 - 协议:FTP,加密:根据服务器设置选择(建议显式 TLS)
使用命令行
ftp
open 你的服务器IP 21
(然后输入用户名和密码)
widows访问成功截图
ftp://ip:21/

七、最终效果
- 每天凌晨自动将 SVN 最新代码同步到指定目录
- FTP 用户只读访问该目录,看到的是干净的文件树(无
.svn) - 整个过程全自动,日志记录在
E:\SVN_Server\Log\sync_log.txt
这套方案已稳定运行两周,解放了运维人员的手动操作,也满足了非开发人员获取最新文档/代码的需求。
八、改进建议
- 使用域名代替 IP:如果未来服务器 IP 再次变更,只需修改 DNS 或 hosts 文件。
- 日志轮转:可加入按日期切割日志的逻辑,避免单个日志文件过大。
- 错误告警:检查
svn update或svn export的返回值,失败时发送邮件通知。
希望这篇文章能帮助到有类似需求的朋友。如果你在搭建过程中遇到问题,欢迎留言交流。


178

被折叠的 条评论
为什么被折叠?



