六、 分支和里程碑的实现
几乎每一种版本控制系统都以某种形式支持分支。使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。在很多版本控制系统中,这是个昂贵的过程,常常需要创建一个源代码目录的完整副本,对大型项目来说会花费很长时间。
轻量级分支/里程碑的含义是,创建分支/里程碑的复杂度是o(1),不会因为版本库的愈加庞大而变得缓慢。在CVS中,创建分支的复杂度是o(n)的,导致大的版本库的的分支创建非常缓慢。
1.Subversion的分支/里程碑
Subversion轻量级分支和里程碑的实现是通过svn cp命令,即带历史的拷贝就是创建快速创建分支和里程碑的秘籍。Subversion的版本库有特殊的设计,当你复制一个目录,你不需要担心版本库会变得十分巨大—Subversion并不是拷贝所有的数据,相反,它只是建立了一个已存在目录树的入口。这种“廉价的拷贝”就是创建分支/里程碑是轻量级的原因。由于Svn的分支和标签是来自目录拷贝,约定俗成是拷贝在 branches/和tags/目录下。所谓分支,tag等概念都只是仓库中不同路径上的一个对象或索引而已,和普通的路径并没有什么本质的区别,谁也不能阻止在一个提交中同时修改不同分支中的数据。里程碑是对某个历史提交所起的一个别名,作为历史的标记,是不应该被更改的。svn的里程碑要建立到 tags/目录下,要求不要在tags/下的里程碑目录下进行提交。但是谁也阻止不了对未进行权限控制的里程碑的篡改。
2.Git 的轻量级分支和里程碑
Git中的分支实际上仅是一个包含所指对象校验和(40个字符长度SHA-1 哈希值)的文件,所以创建和销毁一个分支就变得非常廉价。说白了,新建一个分支就是向一个文件写入41个字节(版本号外加一个换行符)那么简单,自然速度就很快了。 Git的实现与项目复杂度无关,它永远可以在几毫秒的时间内完成分支的创建和切换。这和大多数版本控制系统形成了鲜明对比。
Git的分支是完全隔离的,而Subversion则没有。分支本来就应该是相对独立的命名空间,一个提交一般只能发生在一个分支中。在Git中,其内部的对象层级依赖关系或许和SVN类似,但是其工作树的视图表现形式和SVN完全不同。工作树永远是一个完整的分支,不同的分支由不同的head索引去构建,你不可能在工作树中同时获得多个分支的内容。
Git使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。① 轻量级标签就像是个不会变化的分支,实际上它就是个指向特定提交对象的引用。② 而含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标签本身也允许使用GNU Privacy Guard (GPG) 来签署或验证。
Git的里程碑是只读的,Git完全遵守历史不可更改这一时空法则。用户不能向git的里程碑中提交,否则里程碑就不是标记,而成了一个分支。当然Git允许用户删除里程碑再重新创建指定到不同历史提交。
3.多分支间的切换
SVN中提供了一个功能switch,使用switch可以在同一个工作树上,在不同的分支中进行切换。Git在分支中进行切换使用的命令是checkout。
![f0f400a8edb48352bd7d02fadf2cab88.png](https://img-blog.csdnimg.cn/img_convert/f0f400a8edb48352bd7d02fadf2cab88.png)