介绍

版本控制是开发过程中必不可少的部分,通常项目会选用免费的 SVN 或 Git 作为版本控制工具使用。

之间一直使用 Git,最近一段时间使用 SVN,感受到了不同风格软件的差异。

本文主要介绍我在使用过程中遇到的问题,更系统性地比较请使用 svn git 比较 搜索。

环境

Git 近年来已经成为开源软件版本控制的事实标准,SVN 在这方面已经完全败下阵来。

一款软件是否好用,需要看它的社区用户数量、更新速度、功能数量等等。在这些方面 Git 完全超越 SVN。通过 brew info svnbrew info git 比较最近一年的安装数量,SVN 只有 ~92000 次安装,而 Git 有 ~1788000 次安装,差了一个数量级。

通过比较软件的 Release Notes 可以很容易地看出软件的生命力。

版本控制本身就是一件复杂度非常高的事情,所以 Git 的帮助文档才会非常的长,提供的各种参数也非常的多。

差异

可以通过 svn checkout --helpgit checkout --help 的帮助文档简单比较,可以很容易地发现,SVN 提供的参数要比 Git 少很多。这从侧面也反应出 SVN 功能匮乏。

SVN 相对于 Git 的优点

权限控制

SVN 可以管理每一个目录的权限,指定是否可以更新。Git 中只能通过多个仓库的形式模拟。

文件锁定

SVN 可以在修改文件前对文件上锁,这样其他人就无法提交此文件。Git 可以通过 Git LFS 实现此功能。

此功能意义不大,最好项目在设计时减少对锁定的需求,即尽可能的拆分文件内容,让不同的人可以并行工作。

SVN 相对于 Git 的缺点

依赖网络

  1. 仓库的历史只存在于服务器上,因此查看历史、切换分支都需要通过网络进行,操作缓慢。
  2. 更新时只支持单线程下载文件,当文件数量过多时,浪费大量时间。

合并问题

  1. 无法在合并时将某些文件类型指定为无法合并,因为项目内存在程序生成的文本文件,但其实内容无法使用文本合并。
  2. 合并的算法较少,不如 Git 丰富,导致出现更多的冲突。

忽略属性

通过设置属性 svn svn:ignore * 忽略当前目录下所有文件后,如果这个目录中删除了曾经提交过的文件,那么其他人更新时不会将此文件删除。

路径解析

无法查看含有 @ 的路径的历史,不管没有引号、单引号还是双引号都无法改变此行为。 因为游戏项目中往往存在 model@animation.fbx 命名风格的动画 FBX 文件,这个 BUG 直接导致无法使用 svn log 命令查看历史。

1
2
3
svn log "Assets/monster@idle.fbx"
svn: E205000: Try 'svn help log' for more information
svn: E205000: Syntax error parsing peg revision 'monster@idle.fbx'

检出问题

目标分支中如果没有当前分支中的目录,则切换到目标分支后该目录处于冲突状态。

通配符

无法使用通配符执行命令,例如:svn diff *.cs