ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SVN从入门到实践:安装、IDEA集成与分支冲突解决

SVN从入门到实践:安装、IDEA集成与分支冲突解决 1. 装之前先想明白SVN和Git在工作方式上的根本差异很多教程上来就是下载、安装、下一步、完成但我觉得装SVN之前必须先搞清楚它和Git在工作方式上的差别。不然你后面遇到为什么提交必须联网为什么冲突这么多为什么分支这么别扭的时候会怀疑是自己操作不对其实这就是工具本身的特性跟你没关系。1.1 集中式与分布式的核心差别Git是分布式每个克隆下来的仓库都带着完整历史本地随便commit什么时候push到远端由你自己说了算。SVN是集中式所有提交都直接写进服务器上的中心仓库本地工作副本里只有一份当前代码快照改动记录commit必须网络可达没有本地先存着这个缓冲区。打个比方Git像你写的一份文档在很多人的硬盘里都有全本每个人都能离线改自己的版本SVN像办公室里唯一一份正本文件谁要改就借出来在本子上改完必须还回去下一个人拿到的永远是最新版。从这个比喻能推出两个关键事实。第一SVN的commit天然就是立刻影响全组的行为没有人给你rebase的机会第二SVN的分支在物理上是目录复制而不是Git那种轻量级指针所以长期并行多分支的代价比Git高得多。这不是缺点是模型差异理解了才不会用错。我把两者常见维度整理成一张表方便你直接对照维度GitSVN仓库模型分布式本地有全量历史集中式历史在服务器离线提交可以随便commitpush时才联网不行commit必须联网分支本质指针引用创建成本几乎为零目录拷贝成本随仓库体积上升权限控制弱依赖GitLab/Gitea等平台原生支持目录级读写权限学习曲线概念多stash/rebase/cherry-pick容易绕晕简单直观半天就能上手二进制文件仓库膨胀明显通常要上LFS对大文件支持尚可适合场景开源协作、多人多分支并行小团队、传统企业内网项目1.2 什么项目用SVN反而更顺手说实话我见过不止一个项目组为了Git更现代盲目迁移过去结果分支管理做得一塌糊涂二进制素材把仓库撑到几个GB实习生三天两头把主分支搞得乱七八糟。工具没有绝对优劣只有是否匹配团队现状。下面这几种场景SVN反而更舒服十人以内的小团队大家日常就是update、commit不需要花式分支并行。开发环境就在内网本来就没有异地协同、离线提交的需求。有目录级权限诉求比如外包团队只能看某个业务模块SVN的权限模型几行配置就能搞定Git要靠平台额外控制。仓库里放大量发布包、设计源文件、图标素材团队流程就是谁改了谁提交最新版。团队里混着一批不熟悉Git的新人SVN的全部门槛就是把提交和更新练熟。2. TortoiseSVN和命令行客户端安装小乌龟装完不等于万事大吉概念理清之后开始动手。先说个容易绕晕的点SVN有服务器端和客户端日常开发你面对的是客户端。如果你的公司已经有专人维护SVN服务器你只需要装客户端要是你自己搭环境练手才需要把服务器也装上。2.1 先分清服务器端和客户端服务器端主流方案就两种VisualSVN ServerWindows上有图形界面装完配置一下端口、仓库路径就能用小团队最省心。Apache Subversion更偏Linux运维需要自己写配置、管理apache模块适合有运维能力的环境。客户端就是你日常用的东西TortoiseSVN也就是大家常说的小乌龟集成在Windows资源管理器右键菜单里浏览仓库、checkout、提交都靠它。IntelliJ IDEA的Subversion插件在IDE里直接操作版本控制。命令行svn脚本化操作、排错时特别好用。如果只想本地单机跑通全流程装一个VisualSVN Server再装TortoiseSVN就够了服务器和客户端都齐活后面所有操作都能自己复现。2.2 TortoiseSVN下载安装的实操要点去TortoiseSVN官网下载页能拿到当前稳定版1.14.x系列。页面会区分32位和64位安装包按系统选对即可。注意语言包是单独的安装程序如果你想要中文右键菜单得额外下载中文语言包装一遍装完后在TortoiseSVN的Settings里切换语言。安装过程有个组件树里面有一个选项叫command line client tools这个必须确保被安装到本地。有的版本默认不勾选它很多人装了TortoiseSVN之后去IDEA里配置SVN发现找不到svn.exe根因就是这里漏了。另外两个小提醒Overlay icons文件状态覆盖图标建议保留这样资源管理器里能看到文件和文件夹是绿色、红色还是灰色一眼知道哪些改过。装完需要注销一次系统或者重启一下资源管理器右键菜单才会出现SVN CheckoutTortoiseSVN这些入口刚装完直接右键看不到是正常的。装完随便找个文件夹右键如果能看到TortoiseSVN菜单说明shell扩展加载成功。联动失败、右键没菜单这类问题九成是没重启资源管理器重启一下就好。2.3 命令行svnIDEA集成之前的最后一块拼图这里要讲透一个很多人不理解的事IDEA的SVN插件本身并不实现SVN协议它只是个壳必须调用一个真正的SVN客户端来干活。IDEA支持两种模式svn.exe命令行客户端就是上面说的command line client tools装出来的路径一般在C:\Program Files\TortoiseSVN\bin\svn.exe。SVNKit纯Java实现的SVN客户端库随IDEA分发不装任何东西就能用。我强烈建议配置成svn.exe。原因很实在它和你团队里小乌龟用的是同一个客户端核心工作副本格式兼容性最好。SVNKit的版本如果跟服务器、跟其他人用的客户端版本对不上容易出现莫名其妙的行为差异。装好命令行工具后打开一个cmd窗口验证一下svn --version能打印出版本号就说明成功了。如果提示找不到命令多半是TortoiseSVN安装时没把bin目录加进PATH手动把C:\Program Files\TortoiseSVN\bin加到系统环境变量里即可。3. IDEA集成SVN三个预检查比直接点下一步更重要很多人卡在IDEA集成SVN这步其实问题不在操作而在三个非常容易被忽略的检查点。这三件事的顺序如果错了报错会非常误导人——你以为是自己IDEA坏了其实是插件被关掉了或者svn.exe路径没配。3.1 预检查一Subversion插件是否启用打开IDEA的Settings切到Plugins搜索Subversion。这是IDEA内置插件2020.3之后默认自带正常情况下能看到并且已启用。如果你找了一圈都没有这个插件入口先别急着去搞什么网络问题直接确认是不是用的非官方渠道的精简版IDEA。我帮同事排查过两台电脑都是这种包把版本控制插件给阉割了换回官方安装包之后一切正常。3.2 预检查二svn.exe路径到底填对没有设置入口在Settings → Version Control → Subversion页面上有一个Use command line client的勾选项勾上之后会出现路径框把svn.exe的完整路径填进去比如C:\Program Files\TortoiseSVN\bin\svn.exe填完之后如果配置正确页面下方不会出现红色报错提示。如果一直是红的要么路径写错了要么就是2.2里说的command line client tools压根没装。这里顺手看一眼就行不用重启IDEA。至于账号密码IDEA默认会把凭证存到本地的密码数据库里。存储位置和方式在Settings → Appearance Behavior → System Settings → Passwords里控制。这个配置后面切账号的时候会用到先有个印象。3.3 预检查三工作副本格式和IDEA是否兼容SVN历史上有个著名变化1.7版本把原先每个目录一个.svn文件夹的方式改成整个工作副本根目录一个.svn文件夹元数据集中存到一个SQLite数据库里。1.8又进一步调整了元数据结构。如果你拿到的项目文件夹是被很老版本的TortoiseSVN1.6甚至更早checkout出来的IDEA打开时会提示工作副本格式过旧。处理方式很简单在项目根目录执行svn upgrade或者用TortoiseSVN右键菜单里的Upgrade working copy。升级完可以用svn info查看当前工作副本格式。这块最推荐的团队实践是统一大家的小乌龟版本别让新人用新版checkout完之后老同事的旧版本客户端打不开这个目录。版本漂移带来的不是报错是谁都能打开、唯独某个人打不开的诡异局面。4. 第一次Checkout从仓库URL到本地能跑的项目预检查都过了可以走真正的集成流程了。第一步是拿到仓库地址并验证它可达。4.1 获取仓库URL并验证可达性公司SVN仓库的URL一般是这三种协议之一http://或https://最常见搭配VisualSVN Server或Apache使用svn://svnserve服务纯Subversion自家协议file://本地文件仓库基本只有单机学习才用拿到URL后我建议先用TortoiseSVN的Respository Browser仓库浏览器打开看看。它能直接列出仓库目录树同时会触发一次账号认证。这一步能在正式checkout前就暴露权限问题——如果连浏览都进不去就别往IDEA里填URL浪费时间了。顺带说一个常见误区直接用IDEA去checkout一个错误地址报错信息往往不如小乌龟直观。先用小乌龟验证再回IDEA操作能少踩很多坑。4.2 IDEA里Checkout的完整步骤IDEA的入口在顶部菜单VCS → Get from Version Control → 左边选Subversion然后粘贴仓库URL输入账号密码勾选保存凭证选一个本地目录作为checkout目标。这里有个我强调过很多次的建议本地目录一定要选空目录。千万不要图方便把项目checkout到一个已经有文件的文件夹里。旧文件和版本控制状态混在一起后面IDEA会提示要不要把临时的未跟踪文件加入版本控制你一不耐烦点了Add仓库里就会进一堆垃圾。Checkout完成后IDEA会打开这个目录。如果右下角弹出Unregistered VCS root detected的提示直接点Add把项目根目录注册成版本控制根。不注册的话你的SVN状态完全不会生效文件颜色、提交菜单都是空的。注册完后项目树里会出现一堆颜色标记很多人第一次看到满屏绿色会慌其实这是正常的。IDEA的文件状态颜色大概是这样颜色含义绿色本地新增还没提交到版本库蓝色已修改灰色已被忽略不参与版本控制灰色带删除线文件缺失或被删除4.3 首次提交前把忽略规则配好这一步不做后面有你烦的。Java/Maven项目的target目录、IDEA自己的.idea目录和*.iml文件、Python项目的venv这些全是本地环境的东西。一旦被提交到仓库轻则让别人环境错乱重则把仓库撑爆。IDEA里可以配置忽略Settings → Version Control → Ignored Files把target、.idea、*.iml加进去。但是搞清楚一件事IDEA的忽略只对IDEA自己的界面生效你同事用TortoiseSVN提交的时候这些文件照样会被列出来。要在SVN层面真正忽略得用svn:ignore属性这也是很多Git用户转到SVN之后最不习惯的点——SVN没有.gitignore这种纯配置文件必须给目录设置属性。用TortoiseSVN操作右键目标目录 → Properties → New → Other属性名选svn:ignore值填要忽略的目录名多行可以写多个。用命令行也一样svn propset svn:ignore target .idea *.iml . svn commit -m add ignore rules这里有个典型教训我在一个项目里见过target目录被几十次提交仓库越来越大谁更新都慢最后全组人互相怀疑是网络问题。直到有人查了仓库体积才发现是构建产物在作祟。忽略规则必须在第一天就配好等出了事再补历史垃圾已经清不掉了。5. 日常开发高频操作Update、Commit、冲突处理集成完了回到日常。用SVN干活一天里最频繁的就三件事更新、提交、解决冲突。5.1 Update是什么为什么它是开工第一步SVN没有pull对应的是update。Git的pull本质是fetch加merge而SVN的update是直接把服务器上的新提交合并进你的本地工作副本。这一步是开工前必做的把你的代码基线对到团队最新状态后面所有提交都基于这个新基线。在IDEA里快捷键是CtrlT菜单路径是VCS → Update Project。弹出的对话框里通常选Update to the latest version即可团队里有人指定你要看某个旧版本的情况比较少。有个反差现象我得提醒很多人觉得update只有好处其实update也可能带来冲突——如果服务器上某个文件被别人改过而你本地也改了同一个文件且还没提交update时就会触发冲突提示。这不是bug是正常的合并行为处理方式见5.3。我的日常习惯是上班第一件事update一次改一个大文件动刀之前再update一次准备提交之前最后update一次。三次update换来的是冲突概率直线下降这笔时间花得值。5.2 Commit的正确姿势逐项勾选、写清信息提交的快捷方式是CtrlK打开的Commit对话框会列出所有改动文件。这里和Git最大的不同是SVN的提交是逐项勾选的你得自己决定这次提交带哪些文件。第一次从Git过来的人很容易犯一键全选的毛病结果把上个任务改到一半的文件也一起提交了review的人看得一头雾水。提交信息的质量同样重要。我给团队的模板是[模块名] 类型一句话说明 [用户中心] 修复头像上传接口的NullPointerException [订单模块] 新增导出Excel功能不要写update、修改这种等于没写的信息。SVN提交记录是全组人的共同记忆三个月后排查线上问题翻的就是这些留言。提交前IDEA还会做一次本地预检包括编译错误和代码分析警告。这个检测不要跳过等于免费的代码审查能拦住一批低级错误。还有一个特殊情况如果提交失败比如网络断了、权限不足SVN有个很让人讨厌的机制——它会把工作副本锁住。下次操作会提示你运行cleanup。这不是什么大不了的事右键TortoiseSVN → Clean up一下就解开详细见8.1。5.3 冲突来的时候怎么办三栏合并器的正确用法冲突的发生场景通常是这样的你和同事同时改了同一个文件的相近区域对方先提交成功你后提交提交时被拒提示文件冲突。IDEA会弹出一个冲突文件列表双击文件进入合并界面。这个界面上有三个关键动作Accept Yours保留你的版本。Accept Theirs保留服务器版本。Merge打开三栏合并视图左边是你的改动、右边是服务器版本、中间是合并结果。我的实践经验是几十行以内的小冲突直接进Merge逐块选择涉及大段重构或者业务逻辑交叉的冲突不要一个人闷头拼半小时先把对方叫过来对齐一下意图再决定怎么合并。最怕的操作是随手Accept Yours觉得我本地跑得好好的肯定是我对。对方的改动可能就悄然消失在这条分支线里几周后某个功能突然出bug顺着历史一查才发现是冲突时吞掉的代码。解决完冲突记得点Mark as Resolved这一步是给SVN一个明确的冲突已处理标记不点的话提交还是会被拒。6. 权限问题与svn is not a working copy排错链路用到一定规模权限和报错就像雨后春笋一样冒出来。这两类问题网上问得最多但答案往往散落在各个帖子角落我这里一次性说清楚。6.1 先从报错信息学会判断是账号问题还是权限问题SVN用户权限的管理主要靠服务端。VisualSVN Server是图形界面直接配置Apache Subversion则靠authz文件里面可以按用户、用户组、目录路径分配读写权限比如[/] * read dev_team rw [/trunk/core] external_team r普通开发者在日常工作中遇到权限类报错先对照这张表判断方向别自己瞎折腾本地配置报错信息实际含义处理方向Authentication failed用户名或密码错误检查账号清缓存重新登录Authorization failed / Access forbidden账号有效但没权限访问此路径找管理员调整权限E170013: Unable to connect网络或URL地址不可达检查地址、防火墙、服务状态这里有个很常见的误区新人一看到Authorization failed第一反应是重装客户端其实90%的权限问题是服务端配置问题本地重装一百遍都没用。6.2 账号切换为什么别人能提交我不能SVN客户端默认会缓存认证凭证。TortoiseSVN的凭证缓存在Settings → Saved Data → Authentication data里IDEA的凭证存在密码数据库中。当你需要切换账号的时候光在设置里改用户名是没用的必须把缓存凭证清掉。TortoiseSVN清凭证的路径Settings → Saved Data → Authentication data → Clear allIDEA里清凭证可以去Settings → Appearance Behavior → System Settings → Passwords把保存的密码清掉或者直接把IDEA的密码数据库文件删掉后重启。我处理过一个真实案例某同事离职后公司把账号留下来给新人用结果新人commit出去的记录全都显示成已离职同事的名字还以为是IDEA抽风。后来发现就是凭证缓存没清SVN一直拿旧账号在认证。账号还是建议一人一个别共享权限追溯和安全审计都靠它。6.3 svn is not a working copy根因与处理这个报错字面意思是你当前操作的目录在SVN的登记里不是工作副本。它也是最让人摸不着头脑的报错之一。就我的排查经验来看根因基本是下面几类目录是从别人那里直接拷贝过来的.svn目录要么没跟着拷过来要么拷到一半损坏了。这是最典型的一种尤其常见于用U盘、网盘传代码的场景。.svn目录被安全软件误删。某些杀毒软件会把隐藏的.svn目录当成异常文件清理掉一声不吭。你在一个checkout范围外的子目录里执行了svn命令。比如人家只checkout了trunk你却在trunk外面的文件夹里敲svn info。工作副本元数据损坏比如提交过程中电脑断电、磁盘满了、进程被强杀。修复链路我建议按这个顺序走先执行svn cleanup。如果伴随Working copy locked的提示这一步能把锁清掉。用svn info看当前目录是否真的在版本控制内。如果它不在确认下你是不是站错了目录。如果确实元数据损坏且cleanup无用那就别硬救了把本地有改动的文件备份出来注意不要带上.svn目录重新checkout一份再把备份覆盖回去。如果是杀毒软件误删把项目目录加入白名单之后重新checkout。提示永远不要靠拷贝别人的工作副本目录来复用版本控制状态。要复制项目正确的做法是重新checkout而不是直接拷贝文件夹。7. 分支、标签与合并弄清楚SVN的目录复制模型分支话题在SVN里很容易被说成远古操作其实只是模型不同。搞明白它怎么运作配合IDEA用起来并不费劲。7.1 为什么SVN的分支在物理上是目录Git的分支是一个指针创建分支只是写一行的引用所以成本极低。SVN没有这个概念它的分支就是一次目录复制——你把trunk目录复制一份到branches目录下得到一个物理上的独立副本官方管这叫cheap copy廉价复制因为底层是引用的方式做的软复制但还是会体现成完整目录结构。项目的标准目录规约是/trunk 主干日常开发主线 /branches 分支功能开发或发布分支 /tags 标签发版快照只读SVN本身不强制这个结构但所有团队都这么约定因为这是多年踩坑总结出来的。它还有个好处因为分支是目录服务器端可以针对每个目录配置不同权限。比如外包团队只能访问trunk标签和分支目录对他们直接不可见。7.2 在IDEA中创建和切换分支创建分支的入口在VCS → Subversion → Branch or Tag弹窗里选好要复制的源一般是trunk目标路径填branches/xxx填个说明确认即可。整个操作就是一个后台的svn copy。切换分支的入口在右键项目右键项目 → Subversion → Switch...选择目标分支后本地工作副本会切到对应目录。这里有个SVN特有的坑switch会把本地未提交的修改一起带过去。如果你本地有改到一半的代码而目标分支上对应文件也存在这些改动会被带到新分支上。这往往不是你想要的——你只是想切到分支看看结果把半成品代码也带过去了。所以我的建议是切换之前先commit或者把本地改动处理干净。SVN没有Git那种stash如果你确实想临时收起还没完成的修改可以用一个土办法svn diff my_changes.patch svn revert -R .等切完分支再应用补丁svn patch my_changes.patch这样至少能把改动完整保存下来不会丢。7.3 分支合并到主干操作顺序决定成败把功能分支合并回主干IDEA里的入口是VCS → Subversion → Merge from...不同版本IDEA菜单名略有差异有的叫Integrate Directory但功能一样选择源分支选择要合并的版本区间IDEA会把分支上的差异应用到主干目录。合并的本质是把分支上的修改以差异形式应用到目标目录所以主干上对应文件如果有改动照样会冲突解决方式和5.3一致。关于分支合并我有三条被验证过很多次的建议**分支生命周期要短。**功能分支几到两周内就该合并掉。分支拖得越久和主干的偏离越大合并时的冲突数量呈指数增长。**合并前先从主干update分支。**让分支代码跟上主干最新状态把冲突提前暴露在分支环境里解决等合并回主干时就会顺利得多。**不要在分支上偷偷做大重构。**大文件重命名、大范围抽公共方法这种事放在分支上合并时一定会炸。如果非做不可提前跟组里报备合并时一起盯。合并本身也是一次普通的commit提交信息里最好写清楚来源比如merged from branches/v2.0 r123-156方便以后回溯。8. 那些烦人的锁、卡顿和团队协作细节最后聊几个平时查不到、但一定会遇到的实际问题。8.1 Working copy locked和cleanup中断操作的后遗症SVN对工作副本的一致性极其敏感。提交到一半网络断了、update到一半电脑关机、同一份工作副本被两个客户端同时操作都可能留下锁文件。报错原文一般是Working copy xxx locked Please run svn cleanup to remove locks解法很简单TortoiseSVN右键 → TortoiseSVN → Clean up…勾选Break locks和Include externals后执行。或者命令行执行svn cleanup。如果cleanup反复失败说明工作副本的元数据已经有实质损坏别跟它较劲了按6.3的方案重新checkout一份把本地改动补丁导出来打回去。注意不要同时用TortoiseSVN和IDEA去提交同一个工作副本两个客户端进程并发操作是锁的最大来源。用一个为主另一个只做查看。8.2 更新慢、界面卡八成是没配忽略目录IDEA里SVN更新慢到让人怀疑人生Project树滚半天不出来通常不是IDEA的问题而是项目里有太大的未忽略目录——最典型的就是target。SVN在做本地状态扫描时会遍历整个工作副本里的文件哪怕target里有几千个class文件也照单全收。解法就是把4.3里的svn:ignore配置做扎实target、build、node_modules这些目录全都忽略掉。另外还有个设置可以优化update体验在Settings → Version Control → Subversion里把更新时的diff预览改成仅在冲突时弹出。文件多的时候每次update默认弹一堆差异对比窗口真的很耗时间。8.3 给新团队的SVN协作约定工具配好了流程也得跟上。我给项目组定的基本规则看起来简单但执行下来效果很好上班第一件事update下班前把自己负责的修改提交掉不留过夜半成品。提交信息统一格式禁止空信息提交。生成物一律不提交谁提交了target或.idea谁负责清。同一文件的修改冲突约定谁后提交谁主动找对方协调解决。每次发版从trunk打一个tag命名规则如v2.0.1方便随时回溯。最后分享一个我带新人的小习惯新人入职第一天不给他讲概念直接让他checkout一份代码然后随便改一个无关紧要的文件完成一次提交。这个流程走下来他对工作副本、提交、服务器这三者关系的理解比听一小时课都深刻。我这些年帮人排查SVN问题的经验浓缩成一句话SVN的报错其实是最直白的locked就去cleanupnot a working copy就重新checkoutforbidden就找管理员。把这几条对应关系记熟日常开发基本不会再卡壳。如果你们团队正从Git切过来也别急着把SVN当落后的东西先按这套流程跑起来——工具永远是服务业务的稳定和团队习惯比工具本身的时髦程度重要得多。
返回列表