首页 > 代码库 > Git与SCM Intro

Git与SCM Intro

我们为什么需要SCM(software configration management)

     软件配置管理(SCM)主要解决两个问题:1. 软件版本管理 2.团队协作管理。
软件版本管理
     软件在开发过程中,代码和文档总是在不断的变化前进之中,用SCM工具可以帮你记录下这条前进的轨迹,包括代码、文档的变动以及变动的原因,以便于你对项目的演进清晰掌控。软件主版本只有一条轨迹,但是在这条轨迹上会有很多分叉,也就是所谓的分支,后面将结合git的版本控制介绍分支。

团队协作管理
     一个项目一般情况下,不会只由一个人来开发。有协作就会存在合并工作成果,如果没有SCM,这些合并的过程将完全由手工来操作,极其低效。团队协作主要通过分支来实现,将项目的功能点划分到某个分支上,由个某个成员来实现该分支,最后合并在项目的主干上。当然,在一个分支上也允许多名成员协作(表面现象类似于并发编程的协作,但策略与并发编程有异,并发编程主要采用悲观锁,用以防止冲突的发生。而SCM采用了乐观锁策略,假设没有冲突,当冲突发生时,人为手动解决冲突)。

常用的SCM工具
     常见的SCM工具有CVS、SVN和Git。前两者是集中式的,Git是分布式的。集中式意味着你的每次提交都需要传输到服务器上,所以要使用到网络,而且可能由于过于频繁的提交造成性能问题,但由于本地不存在版本库,所以好处是简单。分布式意味着除了服务器上,你的本地也有版本库,你可以脱离网络进行版本的记录,然后再通过网络统一的提交到服务器上的公共版本库,所以提交的次数一定程度上可以减少,总体来说性能更高,除此之外,它还允许一些特有用法,例如只要你还没有提交到公共版本库的版本,你可以放心大胆的将项目转换到曾经的某个版本(在集中式版本控制系统中,其他人可以已经download下来较新的代码,所以做这种操作是不容易的)。这里没有免费的午餐,分布式的特性也给Git带来了一些复杂度提升(主要是一次性的学习成本,后面的使用的时候很easy)。
     下面我们通过Git简要的介绍一些SCM常见的用法。关于Git的详细使用,请见博客内的Git专栏。

Git

一张图说明版本演进

     图片中间有一条项目的主演进版本,在Git中被称为master branch(主分支),通常放在公共版本库中(github或者gitlab)。要修改主分支的代码,常用两种方式:1. 可以直接把公共版本库中的代码克隆到本地版本库,修改后再提交上去,对应于图中主分支上面那条黑线。2.在主分支上再申请一个分支,在申请出来的分支上完成所有的代码修改,最后再合并到主分支上,对应于图中的蓝线。 但所有分支的最终命运不一定都是合并到主分支,例如要发布主分支的一个版本时,我们可以在主分支上拉下一个分支,然后做发布前的最后修改,这个分支在发布后,便失去了作用,该分支对应于图中的Branch B。
     上面这张图只说明了SCM的通用特性,而Git的特点是在每次提交到公共版本库(如图中Master branch及Branch A)前,都可以在本地有多次提交,即local Repository可以在能够记录自己历史的前提下,往前走更长的距离再往公共版本库中提交一次。

分支的作用
     关于使用分支的目的及在Git的应用,请参看博客内的另外一篇文章:http://blog.csdn.net/troy__/article/details/39853321。

标签的作用
     标签用来记录项目的里程碑(重要的时刻),相比于commit的历史记录,更加显眼。标签还经常用来标记分支的最终时刻,分支不再具有生命力,而标签是证明它曾经存在的证据。

Git设置缓冲区的好处
     Git在本地版本库与本地代码中还加入了一层,被称为暂存区(staging area)。本地的代码在修改后,可以先add到暂存区,在多次add到暂存区后再一次性提交到本地的版本库。 这样做的好处是减少了对版本库的接触频率,也就减少版本更新的次数(历史记录的条数),有利于功能划分,且从总体上提高了更新的提交性能(你不用担心add到暂存区的性能,因为add操作只会把要更新的文件添加到更新索引(index)中,在commit时只是读取这些索引就知道要提交哪些文件了)。


个人经验

不强行记忆命令
     我始终认为不应该强行去记忆一些命令,git也好、vi也好、linux同样... 原因有两个:1. 我们要的是命令之后的执行效果,而非命令本身。对于像git、linux这些成熟工具或者系统,只要你能想出来的符合正常逻辑的操作,几乎都提供相应的实现,要用的时候直接网上去查就ok了。对于这种功能与命令之间映射的记忆营养含量极低,你应该把着力点用于提高对全局的把握,而非命令本身。  2.对于常用的操作命令,由于常用,所以你不需要强行记忆,也能记得,对于那些一辈子用一次的命令,就随它去吧...

在命令及GUI之间灵活转换
     我一直对那些完全吹捧命令操作的言论表示怀疑,好像在各种环境下全命令操作能显示出自己的大牛的身份。
命令有命令的好,GUI有GUI的好。在某些场景下,对于功能点较小的操作、或者深度较深的操作,使用命令你可以一下就能达到目的地。比如在代码修改后,你想要使用git提交,我想你可能不会把一只手从键盘上移动到鼠标上,然后打开任务栏上的GUI,然后移动鼠标在面上找到空格输入信息,再点击提交。而是使用命令(windows)Tab+Alt到git bash,然后输入git commit -m "xxx" -a。两种操作,相形之下,结果显然。对于像git diff这样的操作, 在改动较多的情况下,在此时你或许应该使用GUI。所以,在命令和GUI之间灵活切换来提高你的工作效率吧。


Git与SCM Intro