尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Mac上SVN安装与使用全攻略:从Homebrew到IDEA,解决常见坑

Mac上SVN安装与使用全攻略:从Homebrew到IDEA,解决常见坑 前阵子有个朋友跑来找我说公司新接了一个老项目文档和代码都放在SVN上他在Mac上敲svn co直接提示找不到命令问我怎么搞。说实话第一反应我是有点意外的Git都流行这么多年了SVN在不少人眼里已经是“上古产物”可现实里用SVN的团队还真不少尤其是那些运行了七八年甚至十年的存量项目说换分支模型就换成本太高根本折腾不动。所以Mac上装SVN、用SVN这个需求一直都存在只是经常被忽略。这篇文章就把我在Mac上从零折腾SVN的完整过程写出来包括安装方式怎么选、Homebrew踩过的坑、日常干活最常用的几个命令以及和IDEA搭配的注意事项给需要接手SVN项目的朋友一个可以直接照抄的参考。1. 折腾之前先搞清楚Mac上到底该不该用SVN1.1 SVN没死只是你不一定用得上在动手安装之前我建议你先冷静十秒钟想清楚一个问题你手上这个项目是不是真的只能用SVN这个判断很重要因为它决定你后面花多少精力去折腾。SVN是集中式版本控制所有历史记录都存在服务器上分支在逻辑上不过是服务器上的目录拷贝。Git是分布式每个人本地都有一份完整历史。这两种模型各有利弊Git在多人并行、分支切换、离线提交这些场景下确实体验更好但SVN在目录级权限控制、单一可靠服务器、老团队低学习成本这些方面依然有它的优势。尤其是一些老项目代码结构里可能还留着trunk、branches、tags三层目录的标准布局。你用Git硬去兼容这个布局也不是不行但团队成员的习惯、CI脚本里的svn命令、服务器上的钩子脚本全都围绕着SVN转。这时候强行迁Git相当于拿着大刀拆一座住了十年的老房子拆完了还得重新装修。务实一点把SVN用顺手才是正道。1.2 Mac上的SVN现状自带的够不够用很多Mac用户没装过SVN是因为他们对这个命令几乎没感知。这里要说明一个情况旧版本的macOS系统里其实自带了svn命令行工具它是随Xcode Command Line Tools一起装的位置在/usr/bin/svn。你在终端里敲svn --version如果能看到版本号和一堆支持的功能列表说明你机器上已经有一份可用的SVN了。但问题是这份系统自带的SVN版本通常比较老比如可能停留在1.10甚至更早。老版本在访问新协议、握手新TLS证书、兼容新版仓库格式时可能会报各种奇怪的错。我在实际使用中就碰到过svn: E170013: Unable to connect to a repository at URL这种问题最后排查下来就是客户端版本太旧和服务器端协议对不上。所以我的建议是如果你只是临时看一眼代码系统自带的能用就用如果你要长期在这个项目上干活优先装一份新版本省得后面被版本坑了还要回头补课。1.3 先确定你的使用形态安装之前还要明确一件事你打算怎么用SVN这里有三条路线对应的安装策略完全不同纯命令行用户只需要svn这一个二进制就够了推荐Homebrew安装。图形界面用户希望像Windows上的TortoiseSVN那样在Finder里右键操作那就需要额外装一个GUI客户端后面我会详细说。IDE集成用户在IDEA、VS Code里直接提交代码本质上还是要依赖命令行SVN作为底层引擎所以也不可避免地要先解决svn命令的问题。大多数人的工作流其实是最后一条日常在IDE里写代码偶尔到终端里跑一条命令。所以安装策略基本可以概括为不管你想不想用命令行先想办法把新版的svn客户端装上这是所有操作的地基。2. Homebrew装SVN先跨过环境这几道坎2.1 为什么优先推荐HomebrewMac上装软件的方式千千万但对SVN这种开发工具我强烈建议用Homebrew。原因很简单它把依赖管理得干干净净卸载的时候也能一键清掉不会像某些图形安装包那样在你系统里留下各种碎片。好处说完直接上命令brew install svn如果你运气好一条命令下去就装完了。但如果你跟我一样是在公司网络环境下操作或者机器本身有些历史遗留问题那就可能遇到各种报错。下面这几种是我见过最多的逐个说一下怎么处理。2.2 常见报错一提示安装Xcode Command Line Tools如果Homebrew运行的时候提示缺少Xcode Command Line Tools它会弹出一个系统窗口让你确认安装一般路径是xcode-select: error: tool xcodebuild requires Xcode这种情况在全新Mac上尤其常见因为很多开发者根本用不到完整的Xcode但编译软件又需要它提供的工具链。打开终端执行xcode-select --install系统会弹窗点确认等它下载安装完成。装完以后重新跑brew install svn通常就能继续了。2.3 常见报错二网络访问问题国内用户用Homebrew十个人里有八个遇到过这种问题下载依赖的时候卡在某个连接上半天不动最后报curl: (7) Failed to connect to raw.githubusercontent.com port 443。这基本是网络环境导致的公司网络或者运营商链路不稳定都会触发。我个人的处理顺序是这样的先换一个时间段重试避开晚高峰再关掉系统代理相关设置因为有些网络环境下代理反而会拖垮GitHub的访问最后如果还在公司网络可以询问一下网管是否有稳定出口或者直接用手机热点试一下。热点基本都是一次成功亲测有效。提示尽量不要在Homebrew安装过程中频繁CtrlC重试每次都留下半截下载缓存反而更容易碰到缓存损坏的问题。如果下载到一半断了可以执行brew cleanup清一下再重新开始。2.4 常见报错三目录权限问题有一些用户之前用sudo跑过brew或者从迁移助手迁移过系统会导致Homebrew的目录归属错乱。表现是执行任何brew install都会报Permission denied或者Operation not permitted。解决方式是用chown把Homebrew目录归还给当前用户。以Apple Silicon Mac为例Homebrew装在/opt/homebrew下sudo chown -R $(whoami):admin /opt/homebrewIntel芯片的Mac则是sudo chown -R $(whoami):admin /usr/local执行完再重新brew install svn。这里注意sudo chown -R会递归修改整个目录归属如果目录里有其他用户创建的文件也会一并归到你名下在共享机器上操作时要谨慎。2.5 安装完成后的验证装完之后不要急着用先验证一下版本svn --version正常应该会打印类似下面这样的输出svn, version 1.14.2 (r1918595) compiled May 3 2023, 14:52:28看到版本号就说明装好了。如果你的svn --version敲出来还是老的系统自带版本大概率是Homebrew的路径没排在PATH前面。可以通过which svn看它指向哪里如果指向/usr/bin/svn说明需要调整PATH顺序把/opt/homebrew/bin放在前面。一般装完Homebrew会自动配好但如果你之前手动改过s hell配置文件就自己检查一下。3. 图形客户端怎么选小乌龟在Mac上的替代品3.1 Mac用户最尴尬的一个点用Windows做SVN开发的朋友应该都体会过“小乌龟”TortoiseSVN的方便在资源管理器里对着文件点右键就能提交、更新、看日志、打分支图标上还带状态覆盖哪些文件改了、哪些是新加的一目了然。对Mac用户来说这个问题一直很尴尬SVN本身没有官方的图形客户端TortoiseSVN也不支持macOS。很多人第一次在Mac上找SVN客户端搜出来的要么是几年前的过时软件要么是收费的昂贵工具要么索性就是乱码汉化版装完就后悔。所以我直接把我试过的几条路整理成表格方便你对着选。客户端收费情况特点适合人群SnailSVN免费基础版够用集成Finder右键菜单有状态图标覆盖体验最接近小乌龟日常提交更新为主偶尔查看历史Cornerstone付费老牌专业客户端支持复杂对比、清理工作副本、强大的历史浏览重度SVN使用者需要处理复杂合并冲突Versions付费界面简洁操作直观轻度使用对界面要求较高命令行IDE免费用IDE的VCS面板提交终端跑svn命令熟悉命令行或者主要写代码不折腾版本操作3.2 SnailSVN的具体使用体验我自己目前主力用的是SnailSVN原因是它跟Finder集成得最好。安装后它会向系统扩展里注册一个Finder Sync Extension你在系统设置里启用之后被SVN管理的文件夹里每个文件右下角就会出现状态标记绿色对号代表正常橙色问号代表未纳入版本控制红色感叹号代表有冲突或错误。操作上对着文件点击右键菜单里会直接出现Update、Commit、Check Out、Show Log等选项基本就是把TortoiseSVN的操作习惯搬到了Mac上。对从Windows转过来的同事来说几乎零学习成本。有一点要注意SnailSVN底层调用的还是系统里的svn命令行所以它的依赖前提是你已经装好了命令行SVN。如果你用Homebrew装了新版svnSnailSVN会自动找到并使用它不用额外配置。这也是为什么我前面强调“先把命令行SVN装好”的原因——Mac上的图形SVN工具基本都是“壳”底下那层还是命令行。3.3 关于“汉化包”和“小乌龟下载”的提醒网上搜SVN相关教程经常能看到“svn汉化包”、“svn小乌龟下载”这类词条。这些基本都是围绕Windows版TortoiseSVN的TortoiseSVN有独立的语言包安装器装完在设置里切一下语言就行。但Mac上的客户端基本都没有中文语言包这个说法哪怕个别软件宣称有中文翻译质量也一言难尽。实践下来的结论是除非你对英文菜单极度不适应否则没必要为了一个图形菜单去折腾语言包。SVN图形客户端就那么几个菜单项无非是Check Out、Update、Commit、Show Log用几次就记住了。真正会让你头疼的其实是第4章里讲的那些错误信息而那些错误信息反而是英文的配着关键字搜解决方案时更好定位。4. 半小时掌握SVN核心操作checkout、commit、update4.1 第一步把代码拿到本地SVN和Git最大的习惯差异在这里Git叫cloneSVN叫checkout。操作目标也不一样Git clone是克隆整个仓库SVN checkout则可以只取某个目录因为SVN的目录本身就是版本库的一部分。svn checkout svn://192.168.1.100/repos/myproject/trunk ~/workspace/myproject这条命令会把服务器上trunk目录下的所有文件下载到本地~/workspace/myproject。执行后会看到每个文件前面打印一个A表示Added就是“新增到本地工作副本”的意思。如果你是第一次连接这个服务器可能会遇到一个交互提示问你要不要永久接受服务器的证书Error validating server certificate for https://...: - The certificate is not issued by a trusted authority. ... (E)dit, (R)etrust, (p)ermanently accept?这里输p回车即可代表永久信任这条证书。如果输错选了E或R后面每次都弹会很烦。4.2 日常操作三件套update、add、commit拿到代码之后日常干活的流程其实就三件事看别人改了啥、改自己的代码、把改动提交上去。更新本地代码svn update在trunk目录下执行SVN会对比服务器版本把所有更新的文件拉到本地。输出里U代表已更新A代表新增G代表合并成功。如果输出C说明某个文件出现冲突这个我在第6章专门讲。添加新文件写完新代码文件后SVN不会像Git那样git add一次就自动跟踪它得先告诉版本库“我要纳入这个文件”svn add src/main/java/com/example/HelloController.java如果文件很多也可以直接加目录svn add src/main/java --force--force参数会递归地把目录下所有未纳入版本控制的文件全部加入待提交列表。提交修改svn commit -m 新增用户登录接口SVN的提交日志一定要写在-m后面不写的话会打开一个文本编辑器让你填很多人第一次用不习惯不知道怎么退出。用-m直接从命令行带上就行干净利落。4.3 查看状态与历史别靠猜我在带新人的时候发现很多人到了SVN操作的第3天还弄不清自己到底改过哪些文件全靠记忆。强烈建议养成提交前先看状态的习惯svn status输出第一列的字母含义大概是标识含义A已添加到待提交列表M文件被修改过D文件被标记为删除?文件未被纳入版本控制!文件缺失比如被直接删除但没执行svn deleteC存在冲突对于带?的未纳入版本控制的文件一定要养成习惯把编译产物、IDE配置文件加入忽略列表不然提交时一不小心就把target或.idea整个提交进去污染仓库。看历史记录用svn log -l 20只显示最近20条提交记录避免日志太长刷屏。想看某次提交改了啥文件加-vsvn log -v -r 1024想看某个文件在工作副本和服务器最新版本之间的差异svn diff pom.xml不带文件名的svn diff会把所有本地未提交修改都显示出来代码评审之前先跑一下自己先看一眼比你直接在网页上开评审被同事吐槽强一百倍。4.4 撤销错误提交的两种姿势人人都会手滑有一天你发现自己把写错的代码提交上去了怎么办这里分两种情况。第一种还没提交只是改了本地工作副本想回退到原始状态。用svn revert 文件名这个命令会丢弃本地所有未提交修改相当于恢复成和服务器一致的状态。执行前一定确认自己的修改不需要了因为它不会二次确认。第二种已经提交到服务器了想撤销这次提交的改动。SVN没有Git那种reset更安全的做法是用merge反向合并svn merge -r 1024:1023 .意思是“把1024版本反向应用到当前目录”执行后代码会变成1024提交之前的状态然后你再svn commit一次提交日志写“Revert r1024”。用这种方式服务器完整保留了1024版本的记录所有人都能追踪到发生了什么事比直接删历史干净得多。4.5 顺手推荐macOS上本机建个测试仓库如果你刚接触SVN建议先在自己电脑上建一个测试仓库练手不用连公司服务器随便折腾不心疼。步骤也很简单# 创建仓库目录 svnadmin create /tmp/testrepo # 按标准布局创建目录 mkdir -p /tmp/work cd /tmp/work svn mkdir file:///tmp/testrepo/trunk \ file:///tmp/testrepo/branches \ file:///tmp/testrepo/tags -m 初始化目录结构 # 检出到本地 svn checkout file:///tmp/testrepo/trunk /tmp/mywork本地file://协议的SVN库用来练习完全够用等你把checkout、update、commit、revert都跑熟了再上公司的服务器心里就有底了。5. IDEA里把SVN配置明白开发效率翻倍5.1 IDEA的SVN配置逻辑纯命令行用起来毕竟不够直观大多数人最终还是在IntelliJ IDEA里完成日常开发。IDEA本身支持Subversion开箱就能用但IDE自身不内置svn可执行文件需要指定一个命令行svn的路径明白这一点后面很多配置问题就能想通了。打开IDEA的设置Preferences - Version Control - Subversion在这个界面里找到Path to Subversion executable如果留空IDEA会自动在PATH环境变量里找svn。如果你用Homebrew安装的一般路径是/opt/homebrew/bin/svn确认路径没问题后重启一下IDEA让VCS相关配置重新加载。5.2 项目如何关联到SVN仓库打开项目之后点击顶部菜单VCS - Enable Version Control Integration选择Subversion。如果项目是从SVN checkout出来的IDEA通常能自动识别出.svn目录不需要手动关联。如果识别不到检查项目的根目录下有没有.svn这个隐藏文件夹ls -la 项目根目录能看到.svn目录就说明这是一个工作副本。如果这目录不存在那你就得用svn checkout重新拉一份再打开。有一点要特别提醒很多Mac用户在Finder里把项目文件夹拷来拷去或者用网盘同步项目目录都很容易破坏.svn目录里的元数据。.svn里存着工作副本的本地状态、服务器地址、版本号等关键信息一旦被截断或同步冲突IDEA会直接不认识这个项目。遇到这种情况不要慌重新checkout一份代码再干活比修复半残的.svn目录靠谱得多。5.3 IDEA里常见的三个坑坑一提交时报“CANNOT_RUN_SVN”或“Command execution failed”。这种情况百分之九十九是IDEA没有找到svn命令路径。回到5.1的配置页手动填入/opt/homebrew/bin/svn重启IDEA解决。少部分情况是svn已损坏或版本过旧重新brew reinstall svn即可。坑二更新文件后本地明明改了但IDEA不显示修改状态。IDEA的VCS状态标识基于.svn元数据如果你在终端里手动改过文件IDEA应该能实时感知。但如果项目是从别的地方拷来的或者IDEA索引还没有刷新可以试试菜单File - Reload All from Disk强制刷新文件状态。坑三IDEA已经是Git项目但某个子目录要单独用SVN管理。这种情况下不要试图把整个项目切换成SVN而是在该子目录上右键Subversion - Add to VCSIDEA支持按目录映射不同的版本控制系统子目录用SVN、外层用Git也能共存。不过这种双版本控制的结构确实容易搞混不到万不得已别这么玩。5.4 VS Code用户的SVN方案顺手提一句VS Code。虽然很多新项目用Git但VS Code里也有几个SVN插件原理都是调用命令行svn把状态结果解析出来显示在源代码管理面板。常用的是SVN插件装好之后在设置里指定svn.path一般设为/opt/homebrew/bin/svn。它在面板里能显示所有修改文件、未版本控制文件操作方式跟Git面板类似从Git切过来的人几乎不需要学。注意VS Code的SVN插件只是把状态和操作封装了一层底层还是命令行。如果命令行的svn: E155004这类工作副本锁定错误图形界面是救不了的还是得回终端执行svn cleanup。6. 权限、忽略规则与冲突处理团队协作的必修课6.1 认证失败的时候问题多半不在你这边团队协作中SVN权限问题出现频率极高。你刚拿到一个账号连服务器时报Authentication failed: svn: E170001如果你确认用户名和密码都没输错那基本可以判断是服务端权限没有配好。SVN服务器的权限体系是集中式的由管理员在服务端配置authz和passwd文件决定用户在客户端这边能做的事情其实非常有限。我能给的建议是不要反复重试一百遍直接找负责维护仓库的同事告诉他你的用户名让他检查authz里是否给了你对应目录的读写权限。SVN支持非常细粒度的权限控制甚至能精确到某个子目录只允许某个人提交。这种特性是Git不容易做到的也是很多老项目坚持用SVN的理由之一。另外如果你在本机切换过多个账号登录SVN会把认证信息缓存在~/.subversion/auth/换号或者密码变更之后有时候会莫名其妙地报认证失败这时候清空认证缓存重新登录即可rm -rf ~/.subversion/auth/*然后再执行一次svn update它会重新弹窗让你输用户名密码。6.2 忽略规则避免把垃圾文件提交上去SVN没有.gitignore那种集中式的忽略文件它对忽略的控制是每个目录上的一个属性叫svn:ignore。理解了这个概念你就知道为啥有些人SVN仓库里会出现一堆target目录因为他只在自己心里“忽略”了SVN层面根本不知道。给某个目录设置忽略规则svn propset svn:ignore target build .idea *.iml .这里propset是设置SVN属性的命令svn:ignore的值是换行分隔的模式列表末尾的.代表当前目录。设置完后用svn status再看被忽略的文件就不会再以?状态出现了。如果你更习惯用编辑器改也可以这样svn propedit svn:ignore .会打开默认编辑器。注意svn:ignore的设置只影响本地工作副本的status显示它本身也是一次变更需要svn commit提交到服务器才能让所有团队成员共享这份忽略规则。6.3 冲突是怎么发生的该怎么优雅处理假设同事A和同事B同时在改同一个文件UserService.javaA先把代码提交了B一执行svn update系统发现B本地文件相对A的提交版本也有修改而且修改的位置重叠没法自动合并就会报告冲突C UserService.java Conflict discovered in file UserService.java. Select: (p) postpone, (df) show diff, (m) merge...新手看到这个界面基本就慌了。实际上处理方式很简单第一步输入p大幅推迟解决先把冲突文件保留下来SVN会生成三个临时文件UserService.java.working你自己的修改版本UserService.java.r1023你更新前的基础版本UserService.java.r1024服务器上的最新版本第二步用IDEA打开UserService.javaIDEA的VCS冲突解析器会展示左边你的版本、右边别人的版本、下方合并结果手动把两边都需要的代码融合到一起删除冲突标记、、。第三步保存文件后回到终端svn resolved UserService.java标记冲突已解决然后再svn commit -m 解决UserService冲突合并A的改动关于冲突我想说的核心经验是不要在冲突发生的那一刻急着解决如果代码上下文比较复杂宁可先用p推迟把当前思路理清楚再解决。强行在惊恐状态下快速合并很容易把别人的代码也改坏后面还要花更长时间修。6.4 工作副本锁定svn cleanup不是万能的SVN的另一个常见问题是工作副本锁定。表现是执行任何命令都报svn: E155004: Run svn cleanup to remove locks (type wc).原因通常是某个SVN操作中途被中断比如你在update的时候CtrlC或者系统崩溃。SVN为了保护工作副本的一致性会在.svn目录里留下锁标记防止多个操作同时写入。解决办法就是按它提示的跑svn cleanup大多数情况下一条命令就搞定了。但如果cleanup也报错或者卡住说明.svn目录的元数据已经损坏比较稳妥的做法是把本地未提交修改先备份出来重新checkout一份然后把备份的修改覆盖回去再提交。虽然粗暴但在很多场景下比修复元数据省时间。7. 顺带提醒一句SVN仓库的安全底线最近我在整理安全相关素材的时候看到不少关于“svn泄露”的案例正好也出现在热搜词里所以单独拎出来说一句。很多团队用SVN管理代码之后直接把工作副本放在Web服务器的根目录下甚至可以访问到/.svn/entries、/.svn/wc.db这些文件别人只需访问几个固定路径就能把整个项目的源文件、提交历史、甚至服务器内部目录结构全拿到手。这类问题在CTF题里很常见但这绝不只是考题而是现实里每天都在发生的安全事故。作为SVN的普通使用者我能给的实操建议有三条第一不要把工作副本直接部署到Web业务服务上。部署时用svn export导出一份“干净”的代码export不会包含.svn元数据目录既能避免泄露也能让部署产物更轻量。第二仓库里坚决不提交敏感信息。数据库密码、密钥、生产环境的配置文件一条都别往SVN里放。哪怕你有SVN访问权限控制也架不住账号被泄露或者仓库权限配置失误。我刚工作那会儿就见过一个项目把生产环境数据库密码直接写在db.properties里提交到仓库后面即使把文件删了历史记录里照样能翻出来这就是把秘密永久印在了发行历史上。第三SVN服务器本身的权限要收敛。authz里只给需要的人最小权限目录级只读权限、部分目录禁止写都是SVN能精细控制的。别图省事给所有人全部读写权限等出事再收就来不及了。这些细节看着跟“Mac上安装SVN”有点远但既然你已经开始用SVN管理代码这些问题早晚会碰到。版本控制工具的价值在于让人能追溯历史但追溯历史的前提是这些历史没有被不该看到的人拿到。到这儿Mac上SVN从安装、环境问题、图形客户端选型、命令行基本操作、IDE集成再到权限、冲突和安全底线基本都过了一遍。说实话SVN这套东西的技术深度不算高真正让人头大的反而是那些“能跑但不好使”的环境问题。我自己踩过最多次的坑就是Homebrew网络问题和IDEA找不到svn命令路径这两件事写进这篇文章希望能帮你少走点弯路。不管你是临时接手老项目还是打算长期在Mac上维护SVN把前面这几步走完日常干活是没有任何问题的。
返回列表