SVN 简介

本文最后更新于:2024年9月8日 晚上

SVN 简介

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

概念

  • repository(源代码库):源代码统一存放的地方。

  • Checkout(提取):当你手上没有源代码的时候,你需要从repository checkout一份。

  • Commit(提交):当你已经修改了代码,你就需要Commit到repository

  • Update (更新):当你已经Checkout了一份源代码,Update一下你就可以和Repository上的源代码同步,你手上的代码就会有最新的变更。

  • 日常开发过程其实就是这样的(假设你已经Checkout并且已经工作了几天):Update(获得最新的代码) -->作出自己的修改并调试成功 --> Commit(大家就可以看到你的修改了)

  • 如果两个程序员同时修改了同一个文件呢, SVN 可以合并这两个程序员的改动,实际上SVN管理源代码是以行为单位的,就是说两个程序员只要不是修改了同一行程序,SVN都会自动合并两种修改,如果是同一行,SVN 会提示文件 Conflict,冲突,需要手动确认。

主要功能

  1. 目录版本控制:CVS 只能跟踪单个文件的历史,不过 Subversion 实作了一个 “虚拟” 的版本控管文件系统,能够依时间跟踪整个目录的变动,目录和文件都能进行版本控制。
  2. 真实的版本历史:自从CVS限制了文件的版本记录,CVS并不支持那些可能发生在文件上,但会影响所在目录内容的操作,如同复制和重命名,除此之外,在CVS里你不能用拥有同样名字但是没有继承老版本历史或者根本没有关系的文件替换一个已经纳入系统的文件,在Subversion中,你可以增加(add),删除(delete),复制(copy)和重命名(rename),无论是文件还是目录,所有的新加的文件都从一个新的,干净的版本开始。
  3. 自动提交:一个提交动作,不是全部更新到了档案库中,就是不完全更新,这允许开发人员以逻辑区间建立并提交变动,以防止当部分提交成功时出现的问题。
  4. 纳入版本控管的元数据:每一个文件与目录都附有一組属性关键字并和属性值相关联,你可以创建,并儲存任何你想要的Key/Value对,属性是随着时间来作版本控管的,就像文件內容一样。
  5. 选择不同的网络层:Subversion 有抽象的档案库存取概念,可以让人很容易地实作新的网络机制,Subversion 可以作为一个扩展模块嵌入到Apache HTTP 服务器中,这个为Subversion提供了非常先进的稳定性和协同工作能力,除此之外还提供了许多重要功能:举例来说,有身份认证,授权,在线压缩,以及文件库浏览等等,还有一个轻量级的独立Subversion服务器,使用的是自定义的通信协议,可以很容易地通过 ssh 以 tunnel 方式使用。
  6. 一致的数据处理方式:Subversion 使用二进制差异算法来异表示文件的差异,它对文字(人类可理解的)与二进制文件(人类无法理解的)两类的文件都一视同仁,这两类的文件都同样地以压缩形式储存在档案库中,而且文件差异是以两个方向在网络上传输的。
  7. 有效的分支(branch)与标签(tag):在分支与标签上的消耗并不必一定要与项目大小成正比,Subversion 建立分支与标签的方法,就只是复制该项目,使用的方法就类似于硬连接(hard-link),所以这些操作只会花费很小,而且是固定的时间。
  8. Hackability:Subversion没有任何的历史包袱; 它主要是一群共用的 C 程序库,具有定义完善的API,这使得 Subversion 便于维护,并且可被其它应用程序与程序语言使用。

优于CVS之处

  1. 原子提交,一次提交不管是单个还是多个文件,都是作为一个整体提交的,在这当中发生的意外例如传输中断,不会引起数据库的不完整和数据损坏。
  2. 重命名,复制,删除文件等动作都保存在版本历史记录当中。
  3. 对于二进制文件,使用了节省空间的保存方法,(简单的理解,就是只保存和上一版本不同之处)
  4. 目录也有版本历史,整个目录树可以被移动或者复制,操作很简单,而且能够保留全部版本记录。
  5. 分支的开销非常小。
  6. 优化过的数据库访问,使得一些操作不必访问数据库就可以做到,这样减少了很多不必要的和数据库主机之间的网络流量。

生命周期

创建版本库

  • 版本库相当于一个集中的空间,用于存放开发者所有的工作成果,版本库不仅能存放文件,还包括了每次修改的历史,即每个文件的变动历史。
  • Create 操作是用来创建一个新的版本库,大多数情况下这个操作只会执行一次,当你创建一个新的版本库的时候,你的版本控制系统会让你提供一些信息来标识版本库,例如创建的位置和版本库的名字。

检出

Checkout 操作是用来从版本库创建一个工作副本,工作副本是开发者私人的工作空间,可以进行内容的修改,然后提交到版本库中。

更新

  • 顾名思义,update 操作是用来更新版本库的,这个操作将工作副本与版本库进行同步,由于版本库是由整个团队共用的,当其他人提交了他们的改动之后,你的工作副本就会过期。
  • 让我们假设 Tom 和 Jerry 是一个项目的两个开发者,他们同时从版本库中检出了最新的版本并开始工作,此时,工作副本是与版本库完全同步的,然后,Jerry 很高效的完成了他的工作并提交了更改到版本库中。
  • 此时 Tom 的工作副本就过期了,更新操作将会从版本库中拉取 Jerry 的最新改动并将 Tom 的工作副本进行更新。

执行变更

  • 当检出之后,你就可以做很多操作来执行变更,编辑是最常用的操作,你可以编辑已存在的文件,例如进行文件的添加/删除操作。
  • 你可以添加文件/目录,但是这些添加的文件目录不会立刻成为版本库的一部分,而是被添加进待变更列表中,直到执行了 commit 操作后才会成为版本库的一部分。
  • 同样地你可以删除文件/目录,删除操作立刻将文件从工作副本中删除掉,但该文件的实际删除只是被添加到了待变更列表中,直到执行了 commit 操作后才会真正删除。
  • Rename 操作可以更改文件/目录的名字,"移动"操作用来将文件/目录从一处移动到版本库中的另一处。

复查变化

  • 当你检出工作副本或者更新工作副本后,你的工作副本就跟版本库完全同步了,但是当你对工作副本进行一些修改之后,你的工作副本会比版本库要新,在 commit 操作之前复查下你的修改是一个很好的习惯。
  • Status 操作列出了工作副本中所进行的变动,正如我们之前提到的,你对工作副本的任何改动都会成为待变更列表的一部分,Status 操作就是用来查看这个待变更列表。
  • Status 操作只是提供了一个变动列表,但并不提供变动的详细信息,你可以用 diff 操作来查看这些变动的详细信息。

修复错误

  • 我们来假设你对工作副本做了许多修改,但是现在你不想要这些修改了,这时候 revert 操作将会帮助你。
  • Revert 操作重置了对工作副本的修改,它可以重置一个或多个文件/目录,当然它也可以重置整个工作副本,在这种情况下,revert 操作将会销毁待变更列表并将工作副本恢复到原始状态。

解决冲突

合并的时候可能会发生冲突,Merge 操作会自动处理可以安全合并的东西,其它的会被当做冲突,例如,“hello.c” 文件在一个分支上被修改,在另一个分支上被删除了,这种情况就需要人为处理,Resolve 操作就是用来帮助用户找出冲突并告诉版本库如何处理这些冲突。

提交更改

  • Commit 操作是用来将更改从工作副本到版本库,这个操作会修改版本库的内容,其它开发者可以通过更新他们的工作副本来查看这些修改。
  • 在提交之前,你必须将文件/目录添加到待变更列表中,列表中记录了将会被提交的改动,当提交的时候,我们通常会提供一个注释来说明为什么会进行这些改动,这个注释也会成为版本库历史记录的一部分,Commit 是一个原子操作,也就是说要么完全提交成功,要么失败回滚,用户不会看到成功提交一半的情况。

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!