先把 SVN 的脑回路切过来
如果你以前主要用 Git,刚进一个 SVN 项目时,最容易出问题的不是命令记不住,而是默认假设错了。
什么时候你必须先把这套逻辑搞明白
- 新接手一个老项目,仓库还在 SVN 上
- 团队里有发布分支、热修分支,但大家说的“分支”其实是服务器目录
- 你明明觉得自己只是本地改改,结果一个
commit就已经把东西发到中央仓库了
SVN 和 Git 最大的几处差别
1. SVN 是中心化的
在 SVN 里,服务器上的仓库就是事实源头。
svn checkout:从服务器拿一个工作副本svn update:把服务器上的最新改动同步到工作副本svn commit:直接把本地改动提交到服务器
也就是说,SVN 没有 Git 那种:
- 先本地
commit - 再远程
push
这两段式缓冲。
你在 SVN 里一旦 commit,就已经影响到别人了。
2. 分支本质上是仓库里的目录
很多 SVN 仓库都会约定这三个目录:
text
/trunk
/branches
/tags通常可以粗暴理解成:
trunk:主干branches:功能分支、热修分支tags:发布快照
所以 SVN 的“建分支”,很多时候不是创建一个抽象对象,而是做一次服务器端复制:
shell
svn copy ^/trunk ^/branches/feature-login -m "create feature-login branch"3. 工作副本是一个有状态的目录
你本地目录里不仅有代码,还有一套 SVN 的元数据。
这也是为什么:
- 复制整个目录给别人,不等于“正确切分支”
- 手工挪文件名,不等于“正确重命名”
- 中途打断更新或合并,工作副本可能会锁住,需要
svn cleanup
4. SVN 的版本号通常是全局递增的
Git 习惯看 commit hash,SVN 更常看修订号,比如 r128、r256。
这会影响你日常说法:
- “这个问题在
r186修了” - “先把
r220挑到发布分支”
如果团队历史上大量使用“版本号”沟通问题,那你最好尽快适应这个语境。
用一天开发流程去理解 SVN
我觉得最容易记的是下面这条线:
checkout到本地,拿到工作副本- 开工前
update - 改代码,配合
status/diff看现场 - 必要时
add/delete/move - 冲突了先处理,再
commit
这套流程里最关键的一点是:提交前必须确认你现在看到的现场就是你想送上服务器的现场。
因为 SVN 不会像 Git 一样给你很多中间缓冲层。
从 Git 切过来时最容易踩的坑
坑 1:把 commit 当成“本地存档”
在 Git 里这么想没问题;在 SVN 里不对。
SVN 的 commit 是共享动作,不是个人草稿箱。
坑 2:手工改文件名,再让 SVN 自己猜
如果你直接在文件系统里把 a.js 改成 b.js,SVN 往往只会看到:
- 一个删除
- 一个未跟踪的新文件
你真正想表达的“重命名”,应该用:
shell
svn move a.js b.js坑 3:以为回滚成本很低
SVN 当然可以撤销,但没有 Git 那么多“先撤回来再说”的缓冲感。
尤其是:
shell
svn revert -R .这种命令一旦敲下去,通常就不是靠一条 reflog 能捞回来的。
我对 SVN 的一个简单判断
SVN 不花哨,但也不神秘。
你只要先接受三件事:
- 中央仓库是唯一事实源
- 分支就是仓库目录
- 工作副本要保持干净、可解释
后面的日常命令其实并不难。

