SVN(Subversion)是一个版本控制系统,用于管理项目代码的修改历史,确保团队协作时能够有效跟踪和管理代码的变更。它类似于 Git,但两者有不同的工作模式和应用场景。
这里我们补充了解一下什么是 RCS 和 CVS ,如果你了解了可以直接跳过。RCS(Revision Control System)、CVS(Concurrent Versions System)和 SVN(Subversion)都是版本控制系统,它们随着时间的发展逐渐演化,目标都是用于管理代码、文档等文件的版本控制,但它们在功能、架构和使用场景上存在不同。
1. RCS(Revision Control System)
RCS 是最早的版本控制系统之一,创建于 1980 年代。
它是一种基于文件的版本控制工具,专门用于管理单个文件的修订历史。
2. CVS(Concurrent Versions System)
CVS 是 RCS 的继承者,它扩展了 RCS 的功能,支持多文件、多用户、并发开发。
CVS 于 1990 年代发布,成为当时流行的集中式版本控制系统之一。
但是 CVS 在处理复杂的分支和合并方面存在局限性。在合并冲突时,开发者需要手动解决,且处理大型项目时效率较低。
SVN 是 CVS 的改进版本,解决了 CVS 的许多问题,成为更现代化、更灵活的集中式版本控制工具。
SVN 背景
SVN(Subversion)诞生于 2000 年,由 CollabNet 创建了 SVN 项目,意在写出一款近似 CVS 操作方式的版本控制系统。同时也在于解决 CVS 的一些缺陷和不足。2000 年2月,CollabNet 联系了Open Source Development with CVS(Coriolis, 1999)的作者 Karl Fogel,问他是否愿意为这个新项目工作。巧的是这时 Karl 已经在和他的朋友 Jim Blandy 讨论一个新的版本控制系统的设计。在1995年,他们两人就开了一家提供 CVS 技术支持的公司,叫作 Cyclic Software。虽然公司已经卖掉了,他们仍然在日常工作中使用 CVS。在使用 CVS 时受到的束缚已经让 Jim 开始仔细思考管理版本化数据的更好的路子。当 CollabNet 打来电话时,Karl 立刻同意为这个项目工作。Jim 征得他的老板 RedHat Software 的同意,让他投入这个项目,而且没有时间限制。CollabNet 雇用了 Karl 和 Ben Collins-Sussman,从5月份开始详细设计。由于 Greg Stein 和CollabNet 的 Brian Behlendorf 和 Jason Robbins 作了积极的推动,Subversion 很快就成为了一个拥有活跃的开发人员社群的应用。最初的设计团队设定了几个简单的目标。他们并不想在版本控制方法论上有新突破。他们只想修补CVS。他们决定 Subversion 应该与 CVS 相似,保留相同的开发模型,但不复制 CVS 最明显的缺点。虽然它不一定是 CVS 的完全的替代品,但它应该和 CVS 相似,从而任何 CVS 用户可以不费什么力气的转换过来。经过14个月的编码,在2001年8月31号,Subversion 可以“自我寄生”了。就是说,Subversion 开发人员停止使用 CVS 管理 Subversion 的源代码,开始使用 Subversion 代替管理自己了。虽然 CollabNet 发起了这个项目。但是 Subversion 像大部分开放源码的项目一样运作,经过不懈的努力,2009年11月,Subversion 被 Apache 所接收并成为了顶级项目。
特征
-
统一的版本号。CVS是对每个文件顺序编排版本号,在某一时间各文件的版本号各不相同。而Subversion下,任何一次提交都会对所有文件增加到同一个新版本号,即使是提交并不涉及的文件。所以,各文件在某任意时间的版本号是相同的。版本号相同的文件构成软件的一个版本。
-
原子提交。一次提交不管是单个还是多个文件,都是作为一个整体提交的。在这当中发生的意外例如传输中断,不会引起数据库的不完整和数据损坏。
-
重命名、复制、删除文件等动作都保存在版本历史记录当中。
-
对于二进制文件,使用了节省空间的保存方法(简单的理解,就是只保存和上一版本不同之处)。
-
目录也有版本历史。整个目录树可以被移动或者复制,操作很简单,而且能够保留全部版本记录。
-
分支的开销非常小。
-
优化过的数据库访问,使得一些操作不必访问数据库就可以做到。这样减少了很多不必要的和数据库主机之间的网络流量。
-
支持元数据(Metadata)管理。每个目录或文件都可以定义属性(Property),它是一些隐藏的键值对,用户可以自定义属性内容,而且属性和文件内容一样在版本控制范围内。
-
支持FSFS和Berkeley DB两种资料库格式。
快速实践
1. 安装 SVN
# liunx
sudo apt-get install subversion
# windows
下载并安装 TortoiseSVN,这是一个常用的 Windows SVN 客户端,集成在右键菜单中,图形界面易于使用。
下载地址: https://tortoisesvn.net/
# mac
brew install subversion
2. 创建 SVN 仓库
在你的服务器上创建 SVN 仓库。
# Linux/macOS
svnadmin create /path/to/repository
# 例如:
svnadmin create /var/svn/myproject
# 目录结构:
Conf 配置文件
Svnserve.conf 权限文件, 可以改用户的读写权限
Authz 用户授权文件
Password 用户密码文件
Db 数据
Hocks
Lock 锁文件
3. 配置 SVN 仓库访问
# 1. 配置用户认证
# 编辑仓库的 conf/svnserve.conf 文件,启用基本的用户认证。
[general]
anon-access = none
auth-access = write
password-db = passwd
# 编辑 conf/passwd 文件来设置用户名和密码
[users]
user1 = password1
user2 = password2
# 2 启动 SVN 服务
svnserve -d -r /path/to/repository
4. 初次提交项目
# 1 导入现有项目代码
假设你已经有一个现成的项目代码,可以将其导入到 SVN 仓库
svn import /path/to/project file:///path/to/repository -m "Initial import"
# 2 检出项目代码
在客户端机器上,将 SVN 仓库中的项目代码检出
svn checkout svn://your-server-ip/myproject
5. 图形化客户端(Windows)
在 Windows 上,可以使用 TortoiseSVN 进行操作。右键点击项目目录,会有相关的 SVN 操作选项:
• SVN Checkout: 从仓库中检出代码。
• SVN Commit: 提交代码到 SVN 仓库。
• SVN Update: 从服务器更新代码。
6. 使用分支和合并
# 创建分支:可以为新功能或新版本创建分支。
svn copy svn://your-server-ip/myproject/trunk svn://your-server-ip/myproject/branches/new-feature -m "Create new branch"
# 合并分支:将分支合并回主干:
svn merge svn://your-server-ip/myproject/branches/new-feature
SVN 详解
SVN 的一些概念
- Repository(源代码库):源代码统一存放的地方
- Checkout(提取):当你手上没有源代码的时候,你需要从 repository checkout 一份
- Commit(提交):当你已经修改了代码,你就需要Commit到repository
- Update (更新):当你已经 checkout 了一份源代码, update 一下你就可以和Repository上的源代码同步,你手上的代码就会有最新的变更
日常开发过程其实就是这样的(假设你已经Checkout并且已经工作了几天):Update(获得最新的代码) -->作出自己的修改并调试成功 --> Commit(大家就可以看到你的修改了) 。
如果两个程序员同时修改了同一个文件呢, SVN 可以合并这两个程序员的改动,实际上 SVN 管理源代码是以行为单位的,就是说两个程序员只要不是修改了同一行程序,SVN 都会自动合并两种修改。如果是同一行,SVN 会提示文件 Conflict, 冲突,需要手动确认。
SVN 架构图
+--------------------+ +--------------------+
| SVN Client | | SVN Server |
| (Checkout/Commit) |<-------->| (Repository Storage)|
+--------------------+ +--------------------+
|
|
+--------------------+
| Repository |
| (Code & History) |
+--------------------+
SVN 流程图
+----------------+ +-------------------+ +-----------------+
| Checkout | --------> | Modify & Develop | --------> | Commit Code |
+----------------+ +-------------------+ +-----------------+
^ | |
| v v
+-------------------+ +-------------------+ +----------------+
| Update (Sync) | <-------- | Resolve Conflicts | | Repository |
+-------------------+ +-------------------+ +----------------+
- Checkout:开发者从中央 SVN 服务器检出代码。
- Modify & Develop:开发者在本地环境中对代码进行修改和开发。
- Commit Code:完成开发后,将本地修改提交到 SVN 服务器。
- Update (Sync):在多人协作中,开发者需要通过更新操作获取其他开发者的最新修改。
- Resolve Conflicts:如果多名开发者修改了相同文件,SVN 会提示冲突,开发者需要手动解决冲突。
常用命令
################## 客户端操作 ##################
# 检出
svn checkout <repository_url> [local_path]
# 更新
svn update [path]
# 提交
svn commit -m "Commit message" [path]
# 查看状态
svn status [path]
# 查看日志
svn log [path]
# 添加文件
svn add <file>
# 删除文件
svn delete <file>
# 还原文件
svn revert [path]
# 移动/重命名文件
svn move <src> <dst>
# 查看未提交的修改
svn diff
# 处理冲突
如果在更新时遇到冲突,SVN 会生成冲突文件。例如,文件 file.txt 的冲突会生成类似 file.txt.r<revision> 的文件。处理冲突后,可以通过以下命令告诉 SVN 冲突已解决。
命令: svn resolve --accept=mine-full <file>
# 显示本地或 运程条目的信息
svn info
# 列出版本库目录的条目
svn list
# 获取帮助
svn help
####### 分支与合并 #######
# 创建分支 (copy)
svn copy <src_url> <dst_url> -m "Create a new branch"
在 SVN 中,创建分支是通过 svn copy 命令完成的,源 URL 通常是项目的主干(trunk),目标 URL 通常是在 branches 目录下新创建的分支。该操作不会实际复制所有文件,而是创建指向源的轻量级分支。
示例:
svn copy https://svn.example.com/repo/project/trunk https://svn.example.com/repo/project/branches/my_feature_branch -m "Create my feature branch"
# 切换到分支 (switch)
svn switch <branch_url>
当分支创建后,开发者可以通过 svn switch 命令将本地工作副本切换到新分支上,从而开始在该分支上进行开发。
示例:
svn switch https://svn.example.com/repo/project/branches/my_feature_branch
# 合并分支到主干 (merge)
**svn merge <branch_url>**
当分支上的开发完成后,通常会将分支的更改合并回主干。这可以通过 svn merge 命令来实现,SVN 会将分支上的更改应用到当前的工作副本上(通常是主干)。
示例:
svn merge https://svn.example.com/repo/project/branches/my_feature_branch
# 合并冲突解决
svn resolve --accept=working <file>
在合并过程中,SVN 会自动合并没有冲突的文件,而对于冲突文件,会生成冲突标记,并要求用户手动解决冲突。解决冲突后,可以使用以下命令告知 SVN 冲突已解决。
示例:
svn resolve --accept=working myfile.txt
# 删除分支
svn delete <branch_url> -m "Delete branch"
####### 权限管理 ########
# 锁定文件 在多人协作开发时,可以锁定文件避免其他人进行修改。适用于需要单人编辑的文件(例如二进制文件)。
svn lock <file> -m "Lock message"
# 解锁文件 解锁已经锁定的文件,允许其他用户修改文件。
svn unlock <file>
# 设置忽略文件 (propset) 设置 SVN 忽略某些特定文件或目录,不将这些文件添加到版本控制中。例如忽略日志文件或编译后的文件。
svn propset svn:ignore <pattern> [path]
# 查看忽略规则 (propget)
svn propget svn:ignore [path]
# 导入项目 (import)
svn import <local_path> <repository_url> -m "Import message"
# 导出项目 (export)
svn export <repository_url> <local_path>
总结
工具 | 类型 | 优点 | 缺点 | 典型使用场景 | 特性 |
---|---|---|---|---|---|
Git | 分布式 VCS | - 分布式架构,支持离线操作- 快速且轻量化的分支管理- 良好的社区支持和扩展性- 高效存储与检索 | - 对新手学习曲线较陡峭- 合并冲突时复杂项目的管理较为繁琐 | - 开源项目- 大规模分布式团队开发 | 分布式版本控制,完全本地操作,无需依赖中央服务器,支持分支和合并操作 |
SVN | 集中式 VCS | - 简单易用,学习曲线平缓- 中央服务器可控制代码访问- 高效处理大文件 | - 依赖中央服务器,离线操作有限- 分支管理较重,操作较慢 | - 小型团队项目- 非分布式环境 | 集中式版本控制,强制服务器端版本库,线性历史 |
Mercurial | 分布式 VCS | - 学习曲线平缓- 分布式架构,与 Git 类似- 处理大项目性能较好 | - 社区活跃度较 Git 低- 一些高级功能相比 Git 较弱 | - 开源项目- 分布式开发环境 | 分布式版本控制,轻量高效,操作简便,集中于简化分布式工作流 |
Perforce | 集中式/分布式混合 VCS | - 强大、快速,适合处理超大规模项目- 优秀的大文件和二进制文件管理- 分布式和集中式混合模式 | - 配置复杂,非开源- 商业授权费用较高 | - 游戏开发- 大型企业软件开发 | 集中式版本控制,支持大规模企业项目,高效的文件管理和大文件支持 |
CVS | 集中式 VCS | 早期版本控制工具,简单易用,适合小型团队协作 | 功能较老旧,版本控制不够灵活,不支持原子性提交,分支操作复杂 | 适用于历史项目或小型团队,简单的版本管理场景 | 早期集中式版本控制,支持并行开发,历史版本管理 |
致谢
更多内容欢迎点击阅读原文,喜欢文章的话,也希望能给小编点个赞或者转发,你们的喜欢与支持是小编最大的鼓励,小巫编程室感谢您的关注与支持。好好学习,天天向上(good good study day day up)。
- TortoiseSVN 官网 TortoiseSVN 官网[1]
- Subversion 官网 Subversion 官网[2]
参考资料
[1] TortoiseSVN 官网: tortoisesvn.net/
[2] Subversion 官网: subversion.apache.org/