SVN 使用笔记

集中式版本管理工具集大成者。

术语(Terminologies)

安装(Setup)

主要涉及以下三个软件,其中VisualSVN = Subversion + GUI管理界面:

SVN 是集中式代码管理的集大成者。其架构是典型的C/S结构,Server 端保存着一份最完整的版本,并且分配多个客户端的权限。其安装和基本配置如下教程。

使用(usage)

使用SVN的情景大致为可以分为个人代码管理(Working with Subversion)和团队协作(Working with a Team)。

新建(create)一个远程仓库(repo)

直接用VisualSVN模仿服务器端建立Repo。
1. 创建一个新的仓库(Repo)
2. 选择文件系统

3. 起一个合适的名字

4. 设置恰当的项目目录结构

5. 分配相关人等权限

6. 完成

检出(checkout)

在服务器端初始化一个仓库之后,我们先将其同步到本地:执行Checkout命令可以初次将远程仓库同步到本地(Working Copies)。

检出完成▼

这样我们本地就有了和远程仓库一样的项目副本▼

本地操作:新建文件(new)、删除(delete)、修改(modified)、重命名(rename)

在得到一个远程仓库的本地副本之后,我们就可以在本地的Repo中添加一些文件了。
如,我们可以在test_svn\trunk中新建hello.c,并添加一些代码:

#include "stdio.h"

int main(int argc, char const *argv[])
{
    printf("%s\n", "Hello SVN");
    return 0;
}

注:其他操作和新建文件的过程类似。

提交(commit)

在我们增加了一个文件之后,需要进过addcommit两部来将其提交到服务端的远程仓库,第一步记录一下改变;第二步将本地提交到远程仓库。

提交完成▼

日志(log)

在我们提交的界面,TortoiseSVN给我们留了一块空白处来让我们说明为啥子要提交这个版本。并且,在这些log上可以单击右键,出来很多选项可以进行下一步操作。

比较(diff)

随着开发进程的推进,我们服务器提交了好些版本的代码,此时,我们相比较不同代码的区别,看看自己到底做了哪些改变。如果在没有SVN的时候,我们可能是保存两份代码,然后用BeyondCompare来比较。在SVN中,天然带了这个功能你开发过程中不同版本的代码的改变。

比如,现在我们往hello.c中增加一些代码,然后再提交这个版本。
1. 选中待比较的`commit

2. 与当前工作区比较

3. 选中比较的文件

4. 比较观察

清除(clean up)

用以清除当前工作区的修改,使其与最近一次提交的commit内容一致。

清除成功▼

撤销修改(revert)

如果在修改完成之后,我们不满意,想回到开始工作的状态。我们这里假设我们每次开始时的状态是提交过的。这时候,我们可以执行TortoiseSVN->Revert


撤销完成▼

返回特定版本(revert to this version)

如果我们想回到前面已经被提交过的版本,比如想从前面的版本上开发出一个分支。这时候我们就需要打开TortoiseSVN->Show Log


如果仅仅作为个人的代码版本管理,以上的操作基本就可以胜任了。但若需要和其他人协同维护一份代码,那么可能需要增加一些同步的操作。比如当两个人A和B从远程仓库检出到本地,然后各自添加自己的代码,然后A向服务器提交自己的修改;之后,B也修改好了自己的部分,然后打算提交自己的部分,然后被提示如下:

那么这时候,我们需要去解决这个冲突,请参考冲突(confilicts)一节。

更新(update)

SVN Update是提交(commit)的反方向的,是将服务器端的最新版本更新到本地。

▼在无冲突的情况下update完成,本地的Working Copy和远程的Repo保持一致。

冲突(conflicts)

但是,有时候我们在update之后就进行自己的工作,进行修改;而此时别人将他自身的修改update到Repo中。当我们修改完之后update到Repo就有可能遇到冲突▼


▼需要将Repo上的最新版下载下来

▼选择需要合并的文件

▼对比修改

▼修改完成

▼提交合并之后的最终版本

锁(lock/unlock)

锁的功能是将冲突防范于未然。当我将某个文件或者文件夹TortoiseSVN->Get Lock,并且可以添加锁文件的一些信息,比如自己的联系方式。此时别人就无法对被锁的文件进行提交。
▼甲方将文件锁住

▼乙方无法提交被锁定的文件

此时,就需要我们人工去和锁上文件的开发人员进行协商。请他释放对文件的锁TortoiseSVN->Release Lock...。▼

分支(branches)

使用分支一般发生在以下两种情景:
1. 一个人自己写着写着一个代码,或者突然跑过来一个人说能不能在你现在主干的代码上改一下一个特性看一下效果。但是我们自己却不想破坏现在的工作现场,不然待会还要还原现场,又不像复制+粘贴保留一个副本,我们就是用上branches来充当临时缓冲区的功能,用完删掉就可以了。当然,如果试验完临时的特性之后觉得还不错,就可以merge进来。
2. 需要从当前trunk上分出一个分支来长期发展,也就是说之后将会保持两条线向前发展,这时候也是需要分支的。

以下就以生成主干trunk为例进行演示:

  1. 右键选中我们要为其创建分支的对象(trunk),点击TortoiseSVN->Branch/tag...生成

  2. 此时我们设定的b2是在远程Repo上,需要执行update
  3. ./branches/b2中修改,测试。完成之后如果觉得不测,需要将commit之后才能mergetrunk中。当然也是需要在trunk上右键merge



  4. 如果此时你的trunk也修改相同的内容,就会发生冲突,参考冲突解决之后即可。
  5. 再将修改之后的trunk内容commit到远程Repo。

节点(tags)

节点可以认为是一个milestone。比如可以把某一阶段之后的发行版放在此处,其他的源码管理放在trunk和branches。
▼选定保存tag的位置和名称

tag保存完成

注意:此时tag是保存在服务器上的,需要先同步到本地。可以update把远程Repo的更新下来。

问题(Issues)

书籍(Books)