公司换服务器、项目迁移机房、仓库目录整体挪位置,这三个场景有个共同点:你手头这个开发机上的 Eclipse 工程,连的 SVN 地址要变了。很多老哥第一反应是删除项目重新 checkout,结果把本地一堆未提交的修改、.settings 下的环境配置、甚至 .classpath 的依赖关系全搞丢了,然后花一下午重建工程。说实话这事真没必要那么折腾。无论是 Eclipse 内置的 Team 操作,还是配合 TortoiseSVN(就是俗称的小乌龟),变更 SVN 地址这件事都有更体面的做法,而且有套路可循。这篇就纯粹聊聊我在实际迁移过程中怎么操作、踩过哪些坑、以及换完地址之后怎么确认一切正常。
1. 什么时候需要变更 SVN 地址,动手前先想清楚这几件事
1.1 服务器迁移、路径调整、协议变化:三种典型触发场景
先说最常见的三种情况。
第一种是服务器迁移。公司从旧机房搬到云上,或者老服务器到期换新机器,IP 和域名都会变。比如旧地址是http://192.168.1.10/svn/project,新地址可能变成http://svn.company.com/svn/project,这种情况最典型,仓库目录结构没变,但整个 URL 都换了。
第二种是仓库路径调整。有些团队早期搭 SVN 时目录规划比较随意,后来维护多了才发现trunk/branches/tags的标准结构没建好,或者项目在仓库里的位置变了。比如原来是http://svn.company.com/svn/projectA,项目组重组后 URL 变成了http://svn.company.com/svn/new/projectA,这种只换了路径后半段的情况也很常见。
第三种容易忽略:协议或端口变化。公司上了 HTTPS 证书,明文 HTTP 不让用了,或者 SVN 服务端口从 3690 换成了 8443,URL 里这些看起来不起眼的部分一变,Eclipse 里所有操作都会直接报连接失败。
判断标准其实很简单:你在 Eclipse 里右键项目,Team 菜单下任何操作都报错,或者提示“Unable to connect to a repository at URL ...”,并且你确认是本机网络没问题、服务器也能 ping 通,那十有八九就是 URL 需要变更了。这时候不要急着删项目重搞,先按下面的清单做准备。
1.2 准备工作清单:确认本地状态、记录新旧地址、备份与人员协调
动手之前有几件事必须先确认,不然中途很容易出幺蛾子。
第一,确认本地工作副本是干净的。右键项目,Team → 同步,看看有没有未提交的修改。有的话先 commit 或者至少备份一份 patch。变更 SVN 地址这个动作本身不会动你的本地文件,但如果你在地址切换过程中又去提交,很容易搞混新旧仓库上的版本状态。我一般习惯先把手上活干完,提交干净了再换地址,这样排查问题也容易。
第二,把完整的旧地址记录下来。在 Eclipse 里,选中项目右键,Properties(属性),在 Subversion 相关的页签里能看到当前 URL;如果没有,用 TortoiseSVN 在项目文件夹上右键看“属性”,或者在命令行跑一下svn info都能看到。一定要记录完整 URL,包括最后的/trunk、/branches/xxx路径,别只记到仓库根。因为实际上你工作副本对应的可能不是仓库根,而是某个子目录,地址写错了后面会非常麻烦。
第三,强烈建议备份一份工作副本。不需要整盘 copy,但至少把项目目录复制一份放在磁盘其他位置。特别是里面那个.svn隐藏目录,如果操作中途断了,或者地址填错了,备份能让你一键回到原地。我见过不少同事迁移服务器时玩脱,最后靠这份备份救了命。
第四,和团队约定一个操作窗口。SVN 是集中式版本控制,大家连的是同一个仓库,你一个人换地址的时候如果另一个同事还在往旧服务器提交,两边数据就对不上了。我的习惯是:迁移前通知大家暂停提交 10 分钟,统一换完地址后再继续干活。服务器迁移这种事本来就该有“冻结窗口”,不然新旧仓库的数据同步问题会让人崩溃。
2. Eclipse 内置方案:Team → 切换 的正确打开方式
2.1 为什么不建议删除项目重新检出
很多人的第一反应是:直接把项目删了,重新 checkout 一份不行吗?行,但代价比较大,尤其是项目用了很久的情况下。
删除重来意味着你要重新做三件事:重新在 Eclipse 里导入项目、重新配置本地的编译环境(JDK 版本、编码、Maven 仓库等)、重新处理那些被 SVN 忽略的本地文件(比如数据库配置文件、本地环境变量、IDE 特有的.settings目录)。这些都是你日积月累调出来的东西,重新来一遍费时费力还容易漏。更关键的是,如果你本地有未提交的修改,删除项目再来一遍等于把这些改动全部丢进回收站——虽然文件可能还在磁盘上,但 SVN 的版本关联已经断了,恢复起来特别痛苦。
而 Eclipse 的 Team → 切换(Switch)本质上只是修改工作副本元数据里记录的 URL 信息。SVN 的工作副本在.svn目录(新版本是wc.db数据库)里存着一份“这个目录对应仓库哪个地址”的记录,切换操作就是改这个记录,然后把文件状态做一次增量比对。整个过程不需要重新下载所有文件,本地改动也能完完整整保留,速度极快——哪怕项目里面有几千个文件,也就几秒钟的事。
生活里做个类比:你搬家后,快递公司要派件,你有两个选择——把整个家重新装修一遍(删除重来),或者只改一下收件地址(switch)。正常人都会选后者。
2.2 一步步操作:右键切换,填写新 URL,选择版本
下面把 Eclipse 里的操作步骤完整走一遍。
在Project Explorer或Package Explorer里选中项目,右键。如果你是在工作集(Working Set)外面选中项目,效果一样,但建议选中具体项目而不是某个文件夹,避免漏掉子模块。
菜单路径:Team → 切换(Switch)。有些汉化包显示的是“切换”,英文版是“Switch”,Subversive 插件可能显示为“切换/重新定位(Switch/Relocate)”。点击后弹出对话框。
在对话框的“工具 URL(URL)”一栏,粘贴新的完整 SVN 地址。注意不要填错,这里可以复制浏览器里登录 SVN 后看到的完整路径,或者先在 TortoiseSVN 的仓库浏览器里打开确认一下目录层级再填。
版本(Revision)默认选择“HEAD 版本(HEAD revision)”。如果你想切回某个历史版本,也可以填具体版本号,但这不是本次地址变更的常见场景,保持 HEAD 即可。
下方还有一个“深度(Depth)”选项,默认“无限深度(infinity)”就行。除非你知道自己只需要某一个子目录,否则不要改这个选项。
点击“完成”或“OK”,Eclipse 会开始执行切换操作。窗口左下角或 Console 里会打印 SVN 相关的输出日志,等待它提示完成。如果项目特别大,或者网络到新服务器比较慢,耐心等一会儿。我实测 3000 多个文件的工程,换地址基本是秒级完成。
完成后右键项目,Team → 更新(Update),拉取一下最新代码,确认工作副本和远程仓库状态一致。
这里有一个细节:如果 Team 菜单里没有“切换”选项,先确认你的 SVN 插件装没装。现在 Eclipse Marketplace 里主流的插件是 Subversive 和 Subclipse 两个流派,它们的菜单英文名其实都是 Switch,但汉化后的措辞有些差异——Subversive 有时候叫“切换/恢复”,Subclipse 叫“切换”。实在找不到,就去Window → Preferences → Team → SVN,看看插件是否正常加载。如果插件坏了,推荐直接鼠标右键项目文件夹用 TortoiseSVN 搞定(方法见第 3 部分)。
2.3 插件的差异:Subclipse 与 Subversive 菜单不一样
这里多唠一句,因为很多人在网上搜教程,照着别人的截图操作,结果发现菜单对不上,其实就是插件不同导致的。
Subclipse 是较早流行的 Eclipse SVN 插件,界面比较朴素,Team 菜单里的核心操作有更新(Update)、提交(Commit)、切换(Switch)、显示历史(Show History)。它切换的对话框就是很直接的一个 URL 输入框加版本选择。
Subversive 是 Eclipse 官方社区现在偏推荐的方案,菜单结构稍微复杂一点,Team 菜单里有切换(Switch),并且它的对话框里额外带了一些选项,比如“Ignore ancestry”,通常不建议勾选,除非你想强行把工作副本切成一个和当前完全不同路径的目录。
还有一个需要注意的差异:Subversion 1.7 之前,Eclipse 的 SVN 插件调用的是系统的 JavaHL 库,1.7 之后很多环境改用 SVNKit(纯 Java 实现)。这两种底层实现的缓存目录不一样,Preferences → Team → SVN里能看到当前用的是哪种。换地址之后如果发现认证信息对不上,可能需要到这里的“认证(Authentication)”页签里把旧的密码记录清掉重填。
3. 兜底方案:TortoiseSVN Relocate 与新版命令行的变化
3.1 小乌龟的 Relocate 该怎么用
有些时候 Eclipse 的插件比较老旧,或者在处理大型工作副本时卡顿,这时候我习惯直接用 TortoiseSVN 来改地址。小乌龟对工作副本元数据的处理很直观,而且不依赖 Eclipse 的缓存机制,反而更稳定。
操作方式:在 Windows 资源管理器里找到项目根目录,选中整个项目文件夹,右键,选择TortoiseSVN → Relocate(重新定位)。弹出来的对话框里有From URL和To URL两个输入框:
From URL:填当前工作副本对应的旧地址,比如http://192.168.1.10/svn/projectTo URL:填新地址,比如http://svn.company.com/svn/project
点“确定”以后,小乌龟会遍历.svn目录里的记录,把所有指向旧地址的条目批量改成新地址。这时候要注意一个关键点:Relocate 只做前缀替换,它对目录层级不敏感。也就是说,如果你的旧地址是从/project开始,新地址也应当维持同样的/project后缀;如果你打算连同 project 这个路径也换掉,比如/project变成/new/project,那 From URL 填http://192.168.1.10/svn/project,To URL 填http://svn.company.com/svn/new/project也是可以的,它会精确匹配前缀并替换。但你要确保所有子目录的相对位置不变,否则改出来的路径对不上远程仓库结构,后续 update 会报一堆 missing。
还需要区分一下:小乌龟菜单里除了 Relocate,还有一个Switch(切换)。Relocate 是“改地址”,Switch 是“换分支/换路径”,这两个功能别搞混了。服务器迁移这种场景用 Relocate;从 trunk 切到 branches 这种场景才用 Switch。
3.2 命令行:为什么 svn switch --relocate 消失了
老手可能还记得,SVN 早期版本里有一条命令叫svn switch --relocate OLD_URL NEW_URL,专门用来改工作副本的地址。但这条命令在 SVN 1.7 版本被标记为不推荐使用,到 SVN 1.9 就彻底移除了。官方这么做的原因是:新版 SVN 的switch命令已经能够自动判断当前工作副本对应的仓库根(Repository Root),如果你给的 URL 指向的是同一个仓库的另一个路径,它就做普通切换;如果 URL 指向的仓库根发生了变化,它就顺带完成重新定位。
所以现在在命令行里,如果在项目根目录执行:
svn switch http://svn.company.com/svn/projectSVN 会自动把整个工作副本从旧地址切换到新地址,效果等同于 TortoiseSVN 的 Relocate。不过命令行方式要求你本机装了 SVN 命令行客户端,而且对 Windows 用户来说,平时用得少的话记命令比较费劲,我一般还是推荐直接用小乌龟的图形界面。
另外提醒一下,如果当前工作副本有大量未提交修改,命令行执行svn switch时如果目标地址和当前地址不兼容,会提示冲突。稳妥做法是先把改动提交或备份,再执行切换。
3.3 实在不行怎么办:重新检出并合入本地修改
最后说一种兜底方案。如果 relocation 和 switch 都失败了,比如新旧仓库的目录结构差异太大、历史版本不兼容,或者 SVN 服务端的仓库 UUID 变了导致工作副本被判定为无效,那就只能重新检出。
操作步骤:
- 用一个干净目录对新地址执行
svn checkout,比如svn checkout http://svn.company.com/svn/project D:\workspace\project_new。 - 打开旧工作副本,把里面未提交的修改文件找出来。这一步用 Beyond Compare、IDEA 的 Local History,或者干脆用 TortoiseSVN 的“检查修改(Check for Modifications)”视图,都能列出所有本地改过的文件。
- 把修改过的文件复制到新检出目录的对应位置。复制时注意:如果是
.java、.xml这类代码文件,直接覆盖即可;如果是.classpath、.project、.settings这些 IDE 配置,多半不需要带过来,因为新检出已经生成了标准版本,再用旧的覆盖反而会破坏环境。 - 在新目录里打开 Eclipse,重新导入项目(File → Import → Existing Projects into Workspace)。
- 用对比工具逐文件确认改动完整,然后正常提交。
这个方案最笨,但在异常收敛时最可靠。我上一次遇到必须走这条路的场景,是因为老 SVN 服务器的仓库根目录结构被管理员重新整理过,旧的工作副本路径对应关系彻底断裂,relocate 过去之后怎么都不对,最后用这个方式 20 分钟就搞定了——比重建整个开发环境快得多。
4. 地址更换完成后的验证与常见问题排查
4.1 五个动作确认变更成功
改完地址,别急着关 Eclipse,先花两分钟确认这次变更真的成功了。我自己的验证顺序是:
查看 URL 是否更新。右键项目,Team → 显示资源历史(Show History),如果历史记录能正常加载,说明 Eclipse 和远程服务器已经建立连接。更直接的是命令行进项目根目录,跑
svn info,看输出里的URL和Repository Root是不是新地址。执行一次更新。右键项目,Team → 更新。这一步会从新地址拉取最新代码,能拉下来就说明地址解析、网络、认证都没问题。
做一次小提交测试。新建一个临时文件,比如
README_switch_test.md,随便写两行字,右键 Team → 提交。提交成功的话,说明这个工作副本不仅能读还能写,权限也正常。验证完就把这个临时文件删掉,再提交一次删除操作,把测试痕迹清干净。检查日志完整性。点击项目,Window → Show View → Other → SVN → SVN 资源历史,看看历史记录是否完整。如果历史里最新的提交能对应上自己刚才的提交,说明新旧地址指向的是同一个仓库,没有迁错库。
同步团队其他人的状态。如果你是这个项目的管理员,让团队其他成员也都做一次 switch。这里有个细节:其他人如果还在用旧地址,他们的提交会打到旧服务器上,如果旧服务器已经关了,他们就会一直报错,需要抓紧通知。
提示:
.svn目录里的wc.db数据库保存了工作副本的元数据。如果svn info显示的 URL 是对的,但 Eclipse 里右键项目属性显示的还是旧地址,多半是 Eclipse 视图缓存没刷新。按 F5 刷新项目,或者直接重启 Eclipse 就能解决。
4.2 高频踩坑与排查速查表
我把这些年见过、踩过的问题整理成了一张表,你可以保存下来对照排查:
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 切换后 Eclipse 显示一堆“missing”文件 | 新旧地址路径不对应,或者切换时深度选错 | 撤销本次切换,检查 URL 的目录层级是否一致,用 TortoiseSVN 的仓库浏览器核对 |
| 提示“Unable to connect to a repository at URL” | 网络不通、IP 不对、端口被防火墙拦 | 先浏览器访问新 URL 测试连通性;再确认 SVN 服务端端口和协议 |
| 提示“Authorization failed”或“Forbidden” | 账号密码没变但权限配置变了,或认证缓存还是旧的 | 到 Preferences → Team → SVN → 认证里删除旧凭据,重新输入;找管理员确认账号在新服务器的权限 |
| 切换完成后提交的内容不完整 | 项目里有子文件夹意外被切向了其他地址 | 检查 svn:externals 外部引用,外部引用的 URL 需要单独切换 |
| 团队成员有些人提交成功、有些人一直失败 | 新旧服务器没有同时在线,或者数据未完全同步 | 迁移前确认旧服务器完全冻结,确保所有人统一窗口切换 |
| Eclipse 提示“working copy locked” | 切换过程中 IDE 或小乌龟异常退出 | 在项目目录上运行svn cleanup,然后再试一次 |
| TortoiseSVN 右键菜单找不到 Relocate | 小乌龟版本过老,或右键时选中的不是工作副本根 | 确认文件夹上有绿色/红色小图标(版本化状态),或者在菜单里点开 TortoiseSVN 子菜单查找 |
4.3 我的几点实操习惯
最后分享几个我长期养成的习惯,不一定写在教程里,但对减少事故很有帮助。
第一,迁移前保留旧服务器只读权限至少一周。服务器迁移之后别急着把旧机器关机或者销毁,把它降级为只读模式留几天。万一新地址有问题,还能回退到旧仓库排查。这一周里,团队正常在新地址上开发,旧服务器只做备份参考,不乱写数据就行。
第二,换地址这种操作,最好由项目负责人统一执行,而不是每个人自己摸索。SVN 不像 Git 那么去中心化,地址一换,大家的工作副本都指向新仓库,如果各自操作过程中出了偏差,最后合并回来就是灾难。我见过的稳妥做法是:管理员先在一台机器上试验成功,确认流程没问题,再把操作步骤发到群里,大家照着做,遇到报错统一收集。
第三,本地备份的工作副本不要立刻删。至少保留一个月。因为在迁移初期,你可能会突然发现某个之前忽略的配置文件没带过来,或者某个分支的改动没提交完,这时候旧工作副本就是救命稻草。等新地址稳定运行一个月以上,再清理旧目录,心里踏实得多。
第四,官方文档或者插件版本信息要常看。SVN 和 Eclipse 的插件迭代都挺快,菜单位置、支持的协议、底层 JavaHL/SVNKit 的选择都会影响操作路径。不要拿 5 年前的教程硬套新版软件,最有效的办法就是动手点开 Team 菜单看一眼,再配合这篇文章的步骤走,基本不会迷路。