跳到主要内容

SVN 基础

· 阅读需 12 分钟
Castamere
热爱 Coding

Apache Subversion 通常被缩写成 SVN,是一个开放源代码的集中式版本控制系统(Centralized Version Control System (CVCS)),本篇主要介绍 SVN 的基础功能与指令

SVN

Subversion(SVN) 是一个开源的版本控制系統, 也就是说 Subversion 管理着随时间改变的数据。 这些数据放置在一个中央资料档案库(repository) 中。 这个档案库很像一个普通的文件服务器, 不过它会记住每一次文件的变动。 这样你就可以把档案恢复到旧的版本, 或是浏览文件的变动历史。

SVN vs GIT

可以对 SVN 和 GIT 的部分命令进行一个类比:

SVNGIT
集中式版本控制系统分布式版本控制系统
创建 repositorycreateinit
拉取库到本地checkoutclone
提交更改commitcommit & push
同步代码库updatepull
删除文件deleterm
创建分支copybranch
切换分支switchcheckout
回滚代码revertreset

SVN 生命周期

  1. 创建 repository (create)
  2. 拉取代码到本地 (checkout)
  3. 更新/还原库 (update)
  4. 执行变更 (add, delete, mkdir)
  5. 复查变化 (status)
  6. 修复错误 (revert)
  7. 解决冲突 (diff)
  8. 提交更改 (commit)

创建 repository (create)

对每个库来说,大多数情况下这个操作只会执行一次

svnadmin create /path/to/repository

拉取代码到本地 (checkout)

对程序员来说,当开始接触该项目时,先要从服务器上把现有代码拉取下来,其命令格式如下:

svn checkout URL [PATH] # 可简写为 svn co
# URL: 版本库的路径
# PATH: 本地副本存放的路径(可选),不指定则拉取到当前目录

eg:
svn checkout http://svn.example.com/repo /path/to/local/repository

更新/还原库 (update)

当你有一段时间没有动过这个库,要重新开始修改时,最好先把本机的代码和服务器的同步一下,使用 svn update 即可将本地代码更新到最新版本 (前提是本地没有之前未提交的代码)。除此之外,如果需要回退版本,也可以使用该命令,具体各格式如下:

svn update # 更新到最新版本,可简写为 svn up
svn update -r [版本号] # 更新到指定版本
svn update [PATH] # 更新指定路径的文件

eg:
svn update # 将当前目录及其子目录更新到最新版本
svn update -r 10 # 将当前目录及其子目录更新或还原到版本10
svn update -r 10 readme.md # 将 readme.md 更新或还原到版本10

执行变更 (add, delete, mkdir)

万事俱备之后,可以开始自己的修改,包括增删改等操作。和 git 一样,在添加新文件(touch)/文件夹(mkdir)之后,都要执行 svn add 将文件以及目录的名称添加给版本控制系统。删除文件时应该使用 svn delete 命令,而不是直接使用 rm 进行删除

svn add file
svn delete file # 可简写为 svn del
svn mkdir dir # 相当于 mkdir dir && svn add dir

复查变化 (status)

当你对工作副本进行一些修改之后,你的工作副本会比版本库要新。在 commit 操作之前复查下你的修改是一个很好的习惯。Status 操作列出了工作副本中所进行的变动。正如之前提到的,对工作副本的任何改动都会成为待变更列表的一部分。Status 操作就是用来查看这个待变更列表。其命令格式如下:

svn status [PATH] # 可简写为 svn sts

svn st | grep ^状态 # 获得某状态文件列表
svn st | grep -v ^状态 # 也作 svn st | grep ^[^状态], 过滤掉某状态得到其他状态文件列表

eg:
svn st | grep ^M # 获取 "M" 状态文件列表
svn st | grep -v ^? # 过滤掉 "?" 状态的文件列表

常见状态如下:

状态含义
A预定加入到版本库
M已修改
C冲突
D已删除
?未纳入版本控制
!该项目已遗失(被非 svn 命令删除)或不完整
~版本控制下的项目与其它类型的项目重名
信息

"!" 状态说明

出现原因:使用非 svn 命令(rm 等)删除了此条目。

解决方法:使用 svn update,将被删除的条目更新出来。

正确操作方法:使用 svn delete 删除纳入版本控制的条目

信息

"~" 状态说明

出现原因:删除了一个版本库的文件,新建了一个在原来的位置,新建文件类型与原有文件不一致,而且整个过程中没有使用 svn delete 或是 svn add

解决方法: 将 "~" 文件 svn revert 掉,按照正确操作重新修改。

修复错误 (revert)

当对工作副本做了许多修改之后,但是现在不想要这些修改了,这时候可以进行 revert 操作。Revert 操作重置了对工作副本的修改。它可以重置一个或多个文件/目录。当然它也可以重置整个工作副本。在这种情况下,revert 操作将会销毁待变更列表并将工作副本恢复到原始状态。其命令格式如下:

svn revert [-R] PATH # -R 向下递归删除

eg:
svn revert readme.md # 发现误改了某个文件,可执行此命令将改动撤销掉
svn revert -R scripts # 撤销对 scripts 目录中文件所做的所有改动

解决冲突 (diff)

在最终提交前,我们如果发现系统库有了新的修改,那我们需要与其先进行同步。先使用 svn diff 查看本地有哪些修改,再使用 svn update 更新到最版本,如果在过程中有文件冲突,需要手动解决冲突,最后再进行提交。svn diff 有以下的三种功能

  • 检查本地修改
  • 比较工作拷贝与版本库
  • 比较版本库与版本库

其命令格式如下:

svn diff [-r m:n] [PATH] # 可简写为 svn di

eg:
svn diff # 显示当前目录及其子目录下的所有修改差异
svn diff -r 3 # 对当前修改和版本 3 比较差异
svn diff -r 3:5 # 对版本 3 和版本 5 比较差异
svn diff readme.md # 查看 readme.md 文件的修改差异
svn diff > bug.diff # diff 内容可以导出到文件
备注

svn statussvn diffsvn revert 这三条命令在没有网络的情况下也可以执行的,原因是 svn 在本地的 .svn 文件中保留了本地版本的原始拷贝

提交更改 (commit)

和 git 类似,当本地内容修改到一定量,并且解决好冲突之后,使用 commit 进行提交

svn commit -m "commit message" [PATH] # 可简写为 svn ci
# PATH 可以是文件或目录,不指定 PATH 则默认为当前目录
important

单个问题应当一次性修改合入,避免一个问题合入多次导致中间版本出现编译或功能问题

其他指令

创建分支 (copy, merge)

在 svn 中的分支,其实就是把某个文件夹复制了一份出来,在这个新的分支文件夹下进行修改,等修改完成之后(可能会经过多次提交),再合并回主分支

# 创建分支
svn copy trunk/ branches/my_branch
cd branches/my_branch

# 进行修改
svn commit -m "commit message"

# 合并回主分支
cd trunk
svn merge ../branches/my_branch/

标签 (tag)

标签是版本库中某个特定点的一个快照,它常常被用来做发布版本。标签是只读的,不能对它进行修改或删除。可以看出来 tag 本质上就是一个 branch (命令也相同为 copy ),只不过人为为它赋予了意义,以及一个只读的属性创建标签的命令如下。

svn copy trunk/ tags/v1.0

查看历史信息 (log, cat, info, list)

svn log

用来展示 svn 的版本作者、日期、路径等日志信息

svn log [OPTIONS] [PATH]
# OPTIONS
-r m:n # 查看版本 m 到版本 n 的日志
-l N # 显示最近的 N 条日志
-v # 显示文件目录

eg:
svn log -r 3:4 -l 5 -v readme.md # 查看版本 3 到版本 4 的最后 5 条日志,并显示文件目录

svn cat

用来查看某文件某版本的内容

svn cat -r m readme.md # 查看版本 m 的 readme.md 文件内容

svn info

用来查看某个文件或目录的详细信息,包括路径,最后修改时间,最后修改者,最后修改版本等

svn info [PATH]

svn list

svn list 可以在不下载文件到本地目录的情况下来查看目录中的文件

请作者喝可乐🥤: