Subversion(SVN)是一款开源的版本控制系统,主要用于管理文件和目录的变更,帮助团队协作开发时追踪代码历史、合并修改、回滚错误等,SVN采用客户端/服务器架构,所有版本数据存储在中央仓库,用户通过客户端命令与仓库交互,以下将详细介绍常用SVN命令的用法,涵盖基本操作、版本管理、分支控制等核心场景。
基本操作:检出、提交与更新
SVN的核心流程围绕“检出代码→本地修改→提交更新”展开,对应三个基础命令:checkout
(检出)、commit
(提交)、update
(更新)。
检出(checkout)
作用:从SVN仓库下载最新(或指定版本)的代码到本地,生成工作副本。
语法:svn checkout [仓库URL] [本地路径] [选项]
常用参数:
--username
:用户名(若仓库需认证)--password
:密码(可交互输入,避免明文暴露)-r
或--revision
:指定检出版本号(如-r 100
检出第100版,默认HEAD即最新版)--depth
:控制检出深度(如empty
空目录,files
仅文件,immediates
直接子目录,infinity
全量,默认全量)
示例:
# 从仓库主干检出全量代码到本地./project目录,用户名为dev svn checkout svn://svn.example.com/project/trunk ./project --username dev # 检出指定版本(如第50版),仅包含文件(不递归子目录) svn checkout svn://svn.example.com/project/tags/v1.0 ./v1.0 -r 50 --depth files
提交(commit)
作用:将本地工作副本的修改(新增、删除、修改文件)上传到仓库,生成新的版本号。
语法:svn commit [路径] [选项]
常用参数:
-m
或--message
:提交日志(必填,清晰描述修改内容,如“修复登录按钮样式”)--username
/--password
:认证信息(若未在检出时配置)--keep-local
:提交后保留本地修改(不常用,一般提交后会同步更新本地状态)
示例:
# 提交当前目录的所有修改,日志为“优化查询接口性能” svn commit -m "优化查询接口性能" # 仅提交指定文件(如src/main.py),并附带详细日志 svn commit src/main.py -m "修复main.py中数组越界bug"
更新(update)
作用:从仓库同步最新代码到本地工作副本,避免因版本不一致导致冲突。
语法:svn update [路径] [选项]
常用参数:
-r
:指定更新到的版本号(如-r 100
更新到第100版,默认HEAD)--depth
:调整更新深度(如检出时用empty
,后续可通过--depth immediates
更新子目录)--accept
:冲突解决策略(如mine-full
保留本地修改,theirs-full
保留远程修改,用于批量处理冲突)
示例:
# 更新当前目录到仓库最新版本 svn update # 更新到指定版本(如第80版),并递归更新所有子目录 svn update -r 80 --depth infinity
文件与目录管理:增删改查
开发中常需对文件/目录进行版本控制操作,如新增文件、删除文件、移动/复制文件等。
添加(add)
作用:将未纳入版本控制的文件/目录标记为“待添加”,后续需通过commit
提交到仓库。
语法:svn add [路径] [选项]
常用参数:
--force
:强制添加(如添加已删除但未提交的文件,需先svn delete
本地文件再--force add
)-N
或--non-recursive
:仅添加指定文件/目录,不递归添加子内容
示例:
# 添加新文件config.ini(未纳入版本控制)到仓库 svn add config.ini # 递归添加整个新目录docs及其所有子文件/目录 svn add docs/ # 仅添加目录docs本身,不添加其子内容(适合后续单独控制子目录) svn add docs -N
删除(delete / remove)
作用:从版本控制中移除文件/目录,本地文件默认保留(需--force
强制删除本地文件)。
语法:svn delete [路径] [选项]
常用参数:
-m
:直接附带删除日志(无需单独commit
)--force
:强制删除本地文件(svn delete --force file
会同时删除本地文件和版本记录)
示例:
# 删除文件temp.txt,提交日志为“临时文件无用,删除” svn delete temp.txt -m "临时文件无用,删除" # 强制删除本地文件及版本记录(不可逆,谨慎使用) svn delete --force old_module/
移动(move / mv)与复制(copy / cp)
作用:move
用于重命名文件/目录或移动位置(本质是“删除原路径+添加新路径”,生成一个版本记录);copy
用于创建副本(如分支、标签或文件备份)。
语法:
- 移动:
svn move [原路径] [新路径] [选项]
- 复制:
svn copy [源路径] [目标路径] [选项]
常用参数:
-m
:操作日志(必填,如“重构:将utils.py移至common/utils.py”)
示例:
# 重命名文件test.py为unittest.py svn move test.py unittest.py -m "重命名测试文件" # 移动整个src目录到project/src svn move ./src ./project/src -m "调整项目目录结构" # 复制文件config.py为config_backup.py(本地副本,未提交到仓库需执行commit) svn copy config.py config_backup.py -m "备份配置文件"
版本信息查看:日志、状态与差异
通过查看版本历史、文件状态、修改差异,可定位问题、追溯变更原因。
日志(log)
作用:查看文件/目录的版本变更记录,包括提交者、时间、日志信息。
语法:svn log [路径] [选项]
常用参数:
--limit
:限制显示条数(如--limit 5
显示最近5条)--verbose
:显示修改的文件列表(默认仅显示日志)--grep
:过滤日志关键词(如--grep "bug"
仅显示包含bug的日志)-r
:指定版本范围(如-r 10:20
显示第10版到第20版,-r 20:10
倒序)
示例:
# 查看当前目录最近10条版本日志,并显示修改的文件 svn log --limit 10 --verbose # 查看文件main.py从第5版到第10版的变更日志,过滤包含“登录”的记录 svn log main.py -r 5:10 --grep "登录"
状态(status)
作用:检查本地工作副本与仓库的差异,显示文件状态(如修改、新增、删除、冲突)。
语法:svn status [路径] [选项]
常用参数:
-u
或--show-updates
:同时显示仓库中的最新状态(需联网)-v
或--verbose
:显示文件详细信息(版本号、最后修改者)--no-ignore
:显示被忽略的文件(默认.svnignore
的文件不显示)
状态码说明:
| 状态码 | 含义 |
|——–|———————|
| ` | 未修改 | |
M| 本地修改 | |
A| 已添加(未提交) | |
D| 已删除(未提交) | |
?| 未纳入版本控制 | |
!| 文件丢失或损坏 | |
C` | 冲突(需手动解决) |
示例:
# 查看当前目录所有文件状态(含仓库最新状态对比) svn status -u # 显示详细状态,包括文件版本号和最后修改者 svn status -v
差异(diff)
作用:对比本地修改与仓库版本、或两个版本之间的差异,输出统一差异格式(Unified Diff)。
语法:svn diff [路径] [选项]
常用参数:
-r
:指定版本对比(如-r 10:20
对比第10版和第20版;-r 10
对比本地与第10版)--diff-cmd
:指定差异工具(如--diff-cmd meld
使用图形化工具meld)
示例:
# 对比本地修改与仓库最新版本的差异 svn diff # 对比文件main.py第5版和第10版的差异 svn diff main.py -r 5:10 # 使用图形化工具meld对比本地与仓库版本 svn diff --diff-cmd meld
分支与标签管理
分支用于并行开发(如功能分支、修复分支),标签用于标记重要版本(如v1.0、v2.0),SVN中分支和标签本质是“复制”操作。
创建分支/标签(copy)
作用:从主干(trunk)或其他分支复制代码,创建新的分支或标签目录。
语法:svn copy [源路径] [目标路径] [选项]
目标路径规则:分支通常存于branches/
目录(如branches/feature/login
),标签存于tags/
目录(如tags/v1.0
)。
示例:
# 从主干创建功能分支“用户登录模块” svn copy svn://svn.example.com/project/trunk svn://svn.example.com/project/branches/feature/login -m "创建用户登录功能分支" # 从主干打标签“v1.0正式版” svn copy svn://svn.example.com/project/trunk svn://svn.example.com/project/tags/v1.0 -m "发布v1.0正式版"
切换分支(switch)
作用:将本地工作副本切换到指定分支,用于在不同分支间开发。
语法:svn switch [目标分支URL] [路径] [选项]
常用参数:
--depth
:切换时控制检出深度(与checkout
一致)-r
:切换到目标分支的指定版本
示例:
# 将当前目录切换到“feature/login”分支(需先检出过该分支或主干) svn switch svn://svn.example.com/project/branches/feature/login . # 切换到“feature/login”分支的第30版(仅同步该版本代码) svn switch svn://svn.example.com/project/branches/feature/login . -r 30
合并分支(merge)
作用:将分支的修改合并到主干或其他分支,是分支开发后的核心操作。
语法:svn merge [源分支URL/路径@版本] [目标路径] [选项]
关键参数:
-r
:指定合并范围(如-r 30:40
合并源分支第30版到第40版的修改)--accept
:冲突解决策略(批量处理时使用,如--accept mine-full
保留本地修改)
示例:
# 假设当前在主干目录,合并“feature/login”分支第30版到第40版的修改到主干 svn merge svn://svn.example.com/project/branches/feature/login@30:40 . # 合并后需检查冲突,手动修改后提交,日志为“合并用户登录分支功能” svn commit -m "合并用户登录分支功能"
冲突解决与进阶命令
冲突解决
当本地修改与仓库最新版本冲突时(如同时修改同一文件的不同行),需手动解决冲突后提交。
步骤:
- 更新代码触发冲突:
svn update
→ 冲突文件会标记为C
状态,并生成.mine
(本地)、.r版本号
(远程)临时文件。 - 手动修改冲突文件(删除冲突标记
<<<<<<< .mine
、、>>>>>>> .r版本号
)。 - 标记冲突已解决:
svn resolved [文件路径]
(删除临时文件,状态从C
变为` `)。 - 提交修改:
svn commit -m "解决登录模块冲突"
。
进阶命令
- 导出(export):导出干净代码(不包含
.svn
目录),适合部署:svn export [仓库URL] [本地路径] -r 版本号
。 - 导入(import):将未版本控制的本地文件/目录导入仓库(一次性操作,后续需通过
checkout
使用):svn import [本地路径] [仓库URL] -m "导入初始代码"
。 - 重定位(relocate):修改仓库URL(如服务器地址变更):
svn relocate [新URL] [本地路径]
。
常用SVN命令速查表
命令 | 作用 | 语法示例 |
---|---|---|
checkout |
检出代码 | svn co svn://repo/trunk ./local -m "检出" |
commit |
提交修改 | svn ci -m "提交日志" |
update |
更新本地代码 | svn up |
add |
添加文件/目录 | svn add file.txt |
delete |
删除文件/目录 | svn del file.txt -m "删除" |
log |
查看版本日志 | svn log --limit 5 |
status |
查看文件状态 | svn st -u |
diff |
对比差异 | svn diff -r 10:20 |
switch |
切换分支 | svn sw svn://repo/branch/xxx |
merge |
合并分支 | svn merge -r 10:20 svn://repo/branch |
相关问答FAQs
Q1:SVN和Git的主要区别是什么?
A:SVN是集中式版本控制,依赖中央仓库,离线操作受限(需先update
才能提交),分支/标签是“副本”占用额外空间;Git是分布式版本控制,本地含完整仓库,支持离线提交和分支管理,分支/标签是“轻量级指针”,资源占用低,SVN适合对权限管理要求严格的团队,Git适合开源或分布式协作场景。
Q2:SVN提交时提示“资源冲突”怎么办?
A:冲突原因是本地文件与仓库最新版本存在重叠修改,解决步骤:① 执行svn update
更新代码,冲突文件会生成.mine
和.r版本号
临时文件;② 手动打开冲突文件,删除<<<<<<< .mine
、、>>>>>>> .r版本号
标记,保留需要的代码;③ 执行svn resolved 文件路径
标记冲突已解决;④ 提交修改:svn commit -m "解决冲突"
,若冲突较多,可使用svn merge --accept mine-full
批量保留本地修改(需谨慎检查)。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/17189.html