SVN版本控制

来源:互联网 发布:苹果cms api 编辑:程序博客网 时间:2024/06/15 18:07

    关于SVN的学习,大概是两年多以前为了合作开发学的,确切的说当时的学很是简单,开始时简单合作,所以学的也够用,但是随着后来的项目参与的人越来越多,更多的SVN使用问题不断出现,深感有较为系统学习一下的必要,恰好最近的项目接近尾声,又恰好遇见几本关于SVN的书,故把自己的总结和所学分享一下。

保存什么

    SVN中要存放什么?这个是我们需要关心的一个问题,不用放的存进去,不但浪费空间也会拖慢Export的速度。源代码是必然要保存的,但是根据代码生成的函数API文档需不需要,软件开发文档需不需要?
    简单的说,我们可以这么问:如果没有此文件的最新版本,软件能不能开发、构建、测试、发布?如果软件开发能正常进行,那就不必放进去,比如根据代码生成的函数API文档,每次都可以根据代码重新生成,存入SVN,浪费磁盘空间事小,与代码不同步才事大。

存储原理

    SVN存储采用的是增量算法存储二进制文件,也就是说对源代码而言,每次都保存提交的完整版本显然有些浪费,所以每次提交,SVN存储的只是不同版本文件之间的差异部分,同时SVN保存最新版本的完整版,“最智能”的是,SVN自己会根据一定的情况保存个别版本的完整版,这样根据x=n-1,就可以获取任意版本x的完整版内容。

    SVN使用的是典型的文件和目录结构。

版本原理

    目录和文件是SVN管理的核心内容,文件、目录的改变、移动都会被SVN记录。
    SVN的提交具有原子性,也就是说除非本次要提交的文件全部提交成功,否则一个文件也不会提交到SVN库中,在这个原子操作中,非常重要的一个步骤是,把本次提交的改动打包,并给本次改动写一个编号,所以对每个文件而言,编号并不是连续的,如下图:

    

    也就是说版本号意味着经历了对仓库进行了多少次修改,初始版本为0,代表建库之初的空结构;也可以形象的认为版本号是整个库在每次修改后的一个快照。

.svn

    说完版本号,再来说说.svn文件夹。

    SVN在1.6之前,工作副本中的每个文件夹下都有一个.svn子文件夹;1.6之后,只在工作副本下有一个.svn文件夹。这个文件夹是SVN创建和维护的,用来协助各种SVN命令的执行,它可以帮助SVN识别哪些文件做过修改,哪些文件相对于库中的已过期,可以把.svn文件夹看做本地缓存。.svn是如何做到的?

    之所以.svn文件夹有此作用,与它记录的信息有关:

  • 本地副本最后一次有效更新的版本号、时间戳。
  • 仓库中文件在本地的基准缓存(我认为是上面提到的SVN的智能快照)
    要注意的是,.svn由SVN维护,不要手动修改这里面的任何内容。

操作原理

    结合上面说到的版本编号原理和.svn文件的作用,现在,咱们来说说SVN中的常见操作原理。

    update和commit

    SVN常见的命令,诸如update、commit,在用户操作前,都会检查当前.svn中的文件信息和仓库中的文件信息,主要是版本号比较:
  • 本地副本版本号同于仓库版本号且无内容更改,说明本地文件没有发生任何变化,执行update或commit不进行任何操作。
  • 本地副本版本号同于仓库版本号且有内容更改,说明本地文件更新,执行update无操作,可以正常commit。
  • 本地副本版本号低于仓库版本号且无内容修改,说明库中有其它文件更新,当前文件未变,执行commit无操作,可以正常执行update。
  • 本地副本版本号低于仓库版本号且有内容修改,说明这个文件或目录已经被更改,需要先进行update才能commit,防止冲突。
    总得来说,就是一点,如果你本地副本不是最新的,你不能进行commit操作(delete同理),防止你破坏(或是删除)你没有见过的内容。

    diff

    diff的使用较为常见,常用的有三种:
  • 检查本地修改
  • 比较工作副本与仓库的区别
  • 比较版本库的区别
    第2和第3种的比较容易理解,比较不同版本在仓库中保存的差异部分即可;第1种操作,需要使用到前面提到的.svn,当不使用任何参数时,diff操作比较的是工作文件与.svn中的缓存内容,所以断网也可以操作。

    代码回滚

    有些情况下,需要将代码回滚,分为两种情况:代码尚未提交、代码已经提交
    尚未提交的情况下,直接执行revert命令即可,此时实际上代码回滚到.svn中保存的版本,所以不需要联网即可操作;虽然update后commit也能解决,但是不推荐,需要对仓库进行访问,较慢。
    一旦revert,SVN仓库和.svn都不会保存未改动,需要谨慎操作。
    如果已经提交,需要使用merge解决:
svn merge -r 28:25 pom.xml
    意思是将pom.xml还原到25版本。

解决冲突

    为什么会有冲突?

  • 两个人修改了不同的文件,不会冲突。
  • 两个人修改了同一个文件的不同位置,不会冲突,SVN会很聪明的合并两者的不同。
  • 两个人修改了同一个文件的相同位置,才会发生冲突。
    跟写代码一样,SVN中也分为乐观锁和悲观锁。

    乐观锁

    这个锁真的很乐观,实际上,根本没有锁,当两个人修改相同的一行的代码时,提示如下

<<<<<<< .mine<!--test note2.01-->=======<!--test note2.0-->>>>>>>> .r3842
    然后,这两个人交流,找到解决方法,最终删除这些符号,然后提交。

    悲观锁

    如果两个人修改了相同的代码文件的不同位置,svn可以合并,但是如果是.xls这样的文件,两个人的修改是不可以合并的,这时,为了防止冲突就需要加锁,SVN提供了Get lock和Release lock操作,一旦加锁后,其他人不能修改或提交关于此文件的改动。

    需要注意,这个lock不仅和用户有关,和工作副本也有关:你用用户ld在D盘下的工作副本加锁了,同一台机器上C盘下的工作副本,用户ld写也不能修改被加锁的文件;一旦加锁的文件commit后,SVN就会认为这个文件已经处理好了,会自动解锁。

    如果是代码文件,非常推荐使用乐观锁的形式;即使不得不使用锁,锁住的时间也要尽可能的短。

    有冲突时,同时需要解决的是交流和管理的问题:为什么多个人会修改同一行代码,是分工有问题或是交流有问题。

使用流程

    SVN较为合理的使用流程(以代码为例):

    

结尾

    下面的截图是官方文档中未完全汉化的一段内容,解释的是为什么当你commit后,使用svn log命令不会显示你刚才提交的改动:


    只是跟你说一下,以后可以多读读官方文档了。

推荐

《版本控制之道第2版》

《svnbook-1.6-zh-r3600》(官方说明书,未完全汉化)


3 0
原创粉丝点击