
简介面向银河麒麟操作系统的SVN服务搭建文档系统梳理从源码编译安装Subversion的完整流程帮助需要在国产化Linux环境中搭建版本控制服务的运维和开发人员避开依赖缺失、配置格式等常见坑。文档共1个docx文件压缩包约202KB以分步操作笔记为主覆盖apr、apr-util、SQLite三个依赖组件的下载与编译、SVN主程序安装、环境变量写入、版本库创建以及svnserve.conf、passwd、authz三份文件的权限与口令配置并包含服务启动、客户端访问和开机自启方法。文中特别提醒svnserve.conf首行不可留空、服务端路径尽量用绝对路径等易错细节读者可按步骤直接复现适合国产系统运维、内网部署SVN或从零学习Subversion源码安装的技术人员。已有2788人学习文档篇幅不大但步骤完整能节省自行搜索与排错的时间。1. 银河麒麟装SVN环境到底要装哪几个东西才算数在信创环境里领到一台银河麒麟V10或V11的时候很多人第一反应是去软件商店搜SVN结果不是搜不到就是装上了也不知道怎么建仓库。银河麒麟安装SVN环境这件事麻烦的从来不是“安装”本身而是把服务端进程、仓库目录、账号权限、客户端工具这一整条链路都捋顺。它解决的是团队里的真实问题代码还留在SVN上版本历史不能丢换了麒麟机器之后还得能继续提交、回退、看diff。这篇文章适合两类人一类是刚接手麒麟机器、需要在本机跑起svnserve的运维或开发另一类是桌面端换到麒麟、还要接着用SVN和其他同事协作的工程师。2. 先搞清SVN的组成和权限模型再去碰命令2.1 SVN在国产化环境里为什么还是主力不少团队在Linux上选版本控制工具时默认扑向Git但实际走到内网环境会发现SVN的存量远比想象中大。政府单位、军工院所、制造业企业的历史代码库大量跑在Subversion上有的还挂着一堆Windows端的VisualSVN Server授权。换Git不是不行而是要把历史提交、分支策略、权限模型全部迁移一遍成本和风险都高。我见过不少项目组的选择是继续用SVN把服务端从Windows迁到麒麟上顺手省掉授权费用。从技术形态上看SVN是集中式版本控制服务端只有一个权威仓库客户端通过svn://或http(s)://协议提交。这种模式的优点很契合内网环境版本库集中存放权限可以精确到仓库里的某个子目录审计日志也直观。Git的本地分支能力强但它的提交分散在每个开发者的本地仓库里内网环境下要做集中权限管控反而要额外搭一套GitLab或Gitea。对比下来SVN的“笨”反而成了稳定。SVN服务端有两条主流路线一条是svnserveSubversion自带的轻量守护进程走svn://协议配置简单适合内网小团队另一条是Apache加mod_dav_svn走http(s)://协议能做更细的HTTP层控制适合要跨部门开放访问的场景。这次说的银河麒麟安装SVN环境默认先按svnserve来落地后续需要再升级到Apache方案。2.2 安装源策略yum优先源码编译只做备选银河麒麟基于Linux生态软件源里通常已经打包了subversion。安装时我一般先跑yum而不是直接去官网下源码包。原因很直白发行版仓库里的二进制包把svnserve、svnadmin、svn命令行和运行库都配好了装完直接能用后续安全更新也由系统软件源接管。源码编译虽然能拿到更新版本但要自己处理apr、apr-util、sqlite这些依赖编译失败一次排查依赖的时间就够把十台机器装完了。只有两种场景我才会考虑源码编译一是软件源里确实搜不到subversion二是需要某个特定版本的SVN来匹配现有仓库格式。源码编译的常见做法是解压源码包后依次执行configure、make、make install其中--prefix控制安装路径--with-apr指定apr的config工具路径。这里要提醒一句源码安装的svnserve可能不在/usr/bin下后面写systemd服务时ExecStart路径要跟着改不然起不来。银河麒麟的软件商店在这里帮不上太大忙商店里的软件包偏向桌面应用SVN这种基础服务组件还是交给包管理器更可控。安装前先跑一条sudo yum search subversion看软件源情况比直接闷头装要稳妥。2.3 权限模型先想清楚仓库、用户、路径三段式SVN在svnserve模式下的权限模型由三个文件构成svnserve.conf控制仓库对外行为passwd存用户名和密码authz控制用户能访问哪些路径。可以把它们类比成门锁、门禁卡和房间权限表svnserve.conf决定要不要锁门passwd决定谁能进楼authz决定你能进哪个房间、能碰什么。最容易搞混的是authz的读写关系。r只允许读rw才能提交。很多初学者配完目录权限后提交时报“Access denied”检查一下基本都是把权限写成了r。另一个高频问题是通配符*在SVN的authz里*代表所有已认证用户组名才代表某个用户组。如果不小心写了* r那就是给所有能登录的人开了全库读权限这在多团队共用一个仓库时非常危险。我在实际配置时习惯把规则按“具体目录优先、宽泛规则兜底”来组织。例如先给某个敏感子目录配* 显式禁止所有人再给负责人配ops rw。如果规则之间有重复命中不要依赖匹配顺序来碰运气直接删掉冗余条目让配置一眼能看懂。权限文件改完后不会热加载必须重启svnserve这是一个后面会反复踩的点。2.4 环境组件清单每样东西是干什么的把整个SVN环境拆开会涉及下面这些组件理清关系再去操作就不容易把服务端和客户端混成一团。组件作用备注subversion提供svn、svnserve、svnadmin等命令服务端和客户端都依赖它svnserve服务端守护进程监听3690端口用-r指定仓库根目录svnadmin仓库创建、备份、校验工具不直接参与日常提交RabbitVCSLinux桌面端图形SVN客户端依赖文件管理器集成VSCode SVN插件在IDE里显示文件状态并提交需要系统装有svn命令IDEA Subversion插件IntelliJ系列自带可用SVNKit或命令行客户端这里要明确subversion这个包同时包含服务端和客户端工具。装完它之后本机既能跑svnserve给别人提供仓库也能用svn命令行去checkout别人的仓库。所以实际操作时同一台机器不需要区分“服务端安装包”和“客户端安装包”装一次就都有了。3. 用yum把SVN服务端在银河麒麟上跑起来仓库、配置、开机自启3.1 最小可用的仓库初始化命令先检查软件源里有没有subversion有就直接装。下面这套命令是完整的最小流程# 检查软件源里的可用版本 sudo yum search subversion # 安装服务端和客户端 sudo yum install -y subversion # 验证安装结果能看到svnserve版本信息即可 svnserve --version安装完成后创建专用运行用户和仓库目录。SVN守护进程不建议直接用root跑一旦仓库被非法写入权限边界就是空的。我一般会创建一个系统用户svn专门跑svnserve# 创建无法登录的系统用户用于运行svnserve sudo useradd -r -s /sbin/nologin svn # 创建仓库根目录并初始化第一个仓库 sudo mkdir -p /var/svn sudo svnadmin create /var/svn/repo # 把仓库目录属主交给svn用户 sudo chown -R svn:svn /var/svn # 看看仓库conf目录下有哪些文件 ls -la /var/svn/repo/confsvnadmin create会生成完整的仓库骨架conf目录里是后面要改的配置文件db目录存放版本数据hooks目录放服务端钩子脚本比如提交前强制检查日志等。chown这一步很多人会忘导致后面svnserve以svn用户启动时写不了仓库客户端一提交就报错。如果后面要用root用cron做备份可以把备份命令放到单独脚本里不要让svnserve本身以root身份常驻。3.2 配置svnserve.conf匿名访问必须关进入仓库的conf目录编辑svnserve.conf。先给一份能直接用的配置[general] # 匿名用户不允许访问仓库默认不对内网裸奔 anon-access none # 认证用户可以写入 auth-access write # 密码库文件名路径相对于conf目录 password-db passwd # 授权规则文件名路径相对于conf目录 authz-db authz # 认证领域名只影响客户端缓存显示 realm svn-repo这里几个参数的含义要逐一说清楚。anon-access none是安全底线SVN默认允许匿名读如果不显式关掉仓库代码等于公开在内网里。auth-access write允许登录用户提交如果这个值写成read那所有用户都只能看不能提交。password-db和authz-db填写的是文件名SVN会到conf目录下找这两个文件不要画蛇添足写绝对路径写错了服务起不来。realm字段很多人不理解它不影响权限只会在客户端认证弹窗里显示。如果一台服务器上跑了多个仓库每个仓库的realm要设成不同的名字否则客户端可能串缓存明明切换了仓库却还用旧密码去认证。改完这个文件不会立即生效需要重启svnserve这是svnserve和很多常驻服务不一样的地方。3.3 建立passwd用户库与authz授权规则passwd文件格式极简但正因为极简安全问题容易被忽略。先看标准写法[users] alice 换成高强度密码 bob 换成高强度密码这个文件的密码是明文存储的svnserve模式下没有加密选项所以文件权限必须收紧。创建完账号后执行sudo chmod 600 /var/svn/repo/conf/passwd并把属主改成svn避免其他系统用户直接cat出密码。authz比passwd复杂需要结合分组和路径规则来写。给一份典型配置[groups] ops alice,bob dev carol # 全库默认登录用户只读 [/] * r # 运维组对全库可写 [/] ops rw # dev组只能写src目录 [repo:/src] dev rw * r # private目录默认禁止所有人访问只对ops开放 [repo:/private] * ops rw配置的逻辑是自顶向下逐步细化。注意* 表示空权限也就是显式拒绝它是覆盖之前宽泛读取权限的关键手段。很多团队的svn权限事故就是只写了* r忘了给敏感目录补* 结果新入职员工登录后能把全库代码拉走。authz文件同样要在重启服务后才会生效。这里有个常见误解需要纠正authz的规则不是“先到先得”的简单替换同一路径不要写多条规则尽量让每段配置只承担一个职责。要加新团队时去[groups]里加人不要复制粘贴整段规则否则后期清理起来非常痛苦。3.4 注册 systemd 服务并验证完整提交链路用svnserve直接跑命令行也能启动但机器重启后就没了开发机上还能忍服务器上必须交给systemd管理。在/etc/systemd/system/svnserve.service里写入[Unit] DescriptionSVN Serve daemon Afternetwork.target [Service] Typeforking Usersvn Groupsvn ExecStart/usr/bin/svnserve -d -r /var/svn Restarton-failure [Install] WantedBymulti-user.target这里的-d表示后台运行-r /var/svn指定仓库根目录。特别注意-r参数如果写成-r /var/svn/repo那客户端访问svn://host/repo时实际定位到/var/svn/repo/repo仓库永远提示不存在。-r要指向所有仓库的父目录URL里的路径才是具体仓库名。启动并设置开机自启sudo systemctl daemon-reload sudo systemctl enable --now svnserve ss -ltnp | grep 3690看到3690端口被监听就说明服务起来了。接下来做一次完整冒烟测试新建一个账号去checkout、提交# 用alice账号列出仓库验证认证和授权链路通不通 svn ls svn://127.0.0.1/repo --username alice # 把空仓库拉成工作副本 svn checkout svn://127.0.0.1/repo wc # 新增文件并提交 cd wc echo hello svn readme.txt svn add readme.txt svn commit -m init readme readme.txt最后一步别忘了开放防火墙。麒麟默认可能只放行22端口其他机器访问3690会被直接丢掉sudo firewall-cmd --permanent --add-port3690/tcp sudo firewall-cmd --reload到这里服务端的最小可用环境已经完整跑通了。接下来要解决的是客户端怎么接进来的问题。4. 客户端接入命令行、RabbitVCS、VSCode、IDEA一次配齐4.1 命令行客户端最小交接流程命令行是排查问题时最可靠的工具图形界面在SVN状态显示上出了毛病最后都要靠命令来确认真相。日常开发中高频命令就那么几条# 拉取最新代码 svn update # 查看工作副本状态第一列是文件状态 svn status # 查看本地未提交的改动 svn diff # 查看最近10条提交记录 svn log -l 10svn status的输出怎么看是关键。第一列如果是M表示文件已修改A表示新增待提交?表示未纳入版本控制!表示文件缺失。很多人在IDE里看到红红绿绿的状态标号一头雾水直接跑一条svn status就全清楚了。提交时要养成指定文件的习惯。svn commit -m msg不带文件名会把工作副本里所有改动一起提交很容易把临时文件、调试代码带进仓库。我一般先svn status看一眼再明确指定文件提交。命令行客户端还承担了一个重要职责帮图形界面排查问题。RabbitVCS不显示状态时去终端跑svn info看工作副本是否健康能省下大量瞎折腾的时间。4.2 RabbitVCS图形客户端能用但别硬上RabbitVCS是Linux上最接近TortoiseSVN的图形客户端提供文件管理器右键菜单、状态图标、diff和提交界面。装的时候先搜一下软件源sudo yum search rabbitvcs搜不到就去官方发布渠道拿对应发行版的安装包。安装后要注意RabbitVCS依赖文件管理器的SVN集成接口Nautilus系文件管理器支持最好。银河麒麟V10桌面的默认文件管理器不一定是Nautilus兼容的装上RabbitVCS后右键看不到SVN菜单不是装坏了是文件管理器的插件接口对不上。遇到这种情况不要硬折腾直接退回到命令行或者IDE方案。图形客户端只是提高操作效率的工具不是环境必需项。如果文件管理器能用右键菜单里的SVN Update、SVN Commit、Show Changes摘出来就能覆盖日常操作。冲突发生时RabbitVCS会弹出对比窗口左右两边分别是本地和仓库版本需要手工合并后再标记解决。4.3 VSCode的SVN插件状态标记和提交实操VSCode里装SVN插件后文件列表会出现绿勾、M标记等状态小图标对应热词里的“svn标记文件”。插件本身不带SVN命令行底层调的还是系统装的svn。如果打开工作副本后插件提示找不到SVN去配置项里显式指定路径{ svn.path: /usr/bin/svn }设置完重载窗口插件就能识别工作副本了。日常操作都集中在源码管理面板里改动过的文件会列出来输入提交信息后点SVN: Commit All或者勾选指定文件提交。升级代码用命令面板里的SVN: Update查看某一行是谁改的用SVN: Blame。VSCode插件的状态图标有时会滞后文件确实改了但面板里没变化。先跑svn status确认文件真实状态再在命令面板执行SVN: Refresh刷新。这个组合拳能解决大部分“绿勾没了”的假象。如果刷新后还是不对那就是工作副本本身已经损坏参考下一章的排查流程。4.4 IDEA里配置SVN命令行客户端和SVNKit二选一IDEA系列版本控制面板里对SVN支持得很完整但第一次打开项目时需要让IDEA知道用哪个SVN实现。进入Settings→Version Control→Subversion两种模式一种是Use command line client路径填/usr/bin/svn另一种勾选Use SVNKit (pure Java)也就是不依赖外部svn命令。两者区别在于命令行客户端用的是系统装的SVN版本仓库format升级后跟上比较及时SVNKit是纯Java实现部署省事但版本更新慢一些。我倾向用命令行客户端因为排查问题时报错信息和终端里跑svn报出来的一致好对照。IDEA里还有一个老生常谈的坑旧版本客户端checkout下来的工作副本被新版SVN打开时报“working copy format too old”。解决方式是回到终端执行svn upgrade把.svn目录里的元数据升级到当前工具链支持的格式升级完再回IDEA刷新。注意svn upgrade是本地操作不会影响仓库历史可以放心跑。5. SVN安装使用中的避坑笔记仓库不存在、working copy与绿勾5.1 “svn: 仓库不存在”但明明建过仓库现象客户端执行svn ls svn://192.168.1.10/repo时报Repository ... does not exist但服务器上/var/svn/repo目录是存在的。原因90%的情况是svnserve启动时-r参数指错了层级。如果ExecStart里写的是-r /var/svn/repo那URL里的repo会被追加到这个路径后面实际找的是/var/svn/repo/repo。剩下的情况是服务没监听3690端口或者防火墙把外部访问丢了。解决先本地执行svn ls svn://127.0.0.1/repo验证服务端本身通不通再用ss -ltnp | grep 3690确认监听最后看一眼systemd服务里的ExecStart-r必须指向仓库父目录/var/svn。服务器上配置后用journalctl -u svnserve看启动日志能捕捉到路径解析的具体报错。5.2 “svn is not a working copy”连环报错现象进入某个代码目录执行svn status回应svn: E155007: /path is not a working copy。原因工作副本的.svn元数据目录缺失或损坏。最常见的是开发机之间直接拷贝代码目录拷完之后.svn目录没跟着走或者被文件管理器过滤规则吃掉了。另一个场景是用svn export导出的目录export本来就是不带版本信息的纯净目录自然无法执行SVN命令。解决先用svn info确认当前目录到底是不是工作副本。如果只是需要某个历史版本的文件执行svn cat svn://host/repo/file版本号直接取内容没必要重建整个工作副本。如果目录已经彻底损坏重新svn checkout一份到新目录把旧目录里的本地改动手工合并过去。别试图手工创建.svn目录来骗过SVN元数据格式对不上只会引出更诡异的报错。5.3 绿勾消失文件管理器或IDE里的状态图标不刷新现象文件明明改过RabbitVCS或VSCode里的SVN状态图标消失、一直显示未修改或者干脆全是灰的。原因图形客户端显示SVN状态依赖两层链路底层要能正常读取.svn元数据上层要正确刷新UI缓存。第一层出问题时命令行svn status也会跟着错第二层出问题时只是图标不更新命令行一切正常。解决任何图标异常先跑svn status看真实状态。命令正常而图标不对在VSCode里执行SVN: Refresh强制重读状态RabbitVCS里重启文件管理器进程或者注销重登桌面。如果命令行本身也不正常按5.2的方式检查工作副本健康度。还有一个容易被忽略的点工作副本路径里不要有中文或特殊符号目录名部分文件管理器扩展会解析失败导致状态图标凭空消失。5.4 改了配置不生效重启svnserve是必须动作现象在conf目录里新增了用户、调整了authz权限但客户端用新账号登录时报认证失败或者旧权限还像没改一样。原因svnserve在启动时一次性加载配置文件运行期间不会监听文件变化。修改passwd、authz之后不重启服务客户端拿到的还是旧配置。另一个隐性原因是authz文件里出现了语法错误比如中文字符串多了个空格或全角冒号SVN会直接忽略整个文件段权限回落成默认状态。解决每次改完配置执行sudo systemctl restart svnserve然后用一个携带具体用户名的命令验证例如svn ls svn://127.0.0.1/repo --username alice。不要用kill -HUP指望它重新加载配置svnserve对HUP信号的处理和生产环境预期不一致老老实实restart。给passwd和authz做改动前先备份一份改挂了能秒回滚。5.5 本机能连远程连不上防火墙和监听地址一起查现象服务器本机svn ls svn://127.0.0.1/repo正常办公室里其他机器访问svn://服务器IP/repo超时或拒绝连接。原因麒麟系统的firewalld默认没有放行3690/tcp。这是最常见的情况其次才是svnserve监听在非预期地址上或者云安全组拦截。解决执行sudo firewall-cmd --permanent --add-port3690/tcp sudo firewall-cmd --reload放行端口。放行后从客户端机器用telnet 服务器IP 3690或nc -vz 服务器IP 3690验证端口通不通。如果通说明server端端口已经能到达再排查URL路径。注意svnserve本身默认监听所有网卡如果改过--listen-host参数限制到某个内网IP防火墙放行后依然连不上就去service文件里删掉这个参数。6. 进阶几步多仓库隔离、hotcopy备份与历史版本回退6.1 多仓库隔离一个svnserve管多个项目团队里不同项目不要硬塞进同一个仓库权限会越搅越乱。在/var/svn下为每个项目建独立仓库例如/var/svn/proj-a和/var/svn/proj-b。svnserve的-r /var/svn不用改客户端通过URL区分svn://host/proj-a和svn://host/proj-b。authz里用[proj-a:/]和[proj-b:/]分段控制互不干扰。这样单个仓库hotcopy备份、迁移、权限交接都干净项目结束归档时直接把目录打包拖走不影响其他仓库。6.2 hotcopy快照和dump迁移仓库数据是团队资产备份不能靠cp复制目录。svnadmin给了一套专业工具最常用的是hotcopy它能在svnserve运行状态下做一致性快照不需要停机svnadmin hotcopy /var/svn/repo /backup/repo-$(date %F)恢复时把快照目录放到服务器上改一下systemd服务的-r路径即可。如果要换服务器做跨机器迁移用dump和load的组合它生成的是纯文本格式的完整历史流svnadmin dump /var/svn/repo /backup/repo.dump svnadmin load /var/svn/newrepo /backup/repo.dump注意load之前要先用svnadmin create /var/svn/newrepo建好空仓库。dump文件可以压缩后留存跨版本恢复兼容性比直接搬db目录要好得多。6.3 历史版本回退SVN和Git不一样回退是SVN老用户的高频需求这里有个惯用技巧临时查看旧版本用svn update -r 100 文件名只影响工作副本不产生新提交正式回退则要执行反向合并让回退本身成为一次新的提交记录历史不抹除svn merge -r HEAD:100 svn://127.0.0.1/repo/src . svn commit -m rollback to r100 for src这个命令把src目录从当前HEAD版本回退到100版本工作副本会变成旧代码状态确认无误后提交。回退前先svn log确认目标版本号提交信息里写清是从哪个版本回退过来的团队里其他人看历史时候就能顺着这条记录找回原版。我的习惯是回退类提交都用rollback开头写message半年后排查问题时能一眼定位。希望这些实践能让你在银河麒麟上把SVN环境搭得更顺、用得更稳。本文还有配套的精品资源点击获取