参考:
在一个团队的工作中,掌握版本控制系统的使用是对每一个工程师最基本的要求,作为刚入职的菜鸟我来说,更是需要快速掌握的,下面就简单记录一下svn以及git版本控制的基础知识。
版本控制(Version Control)的含义就是通过某种方式来记录版本库中文件的内容变化,以达到管理和维护版本的开发。其实,我们在学习编程的时候就一直在使用版本控制的理念。例如,在学习C语言的时候,我们会自己进行各种语法,函数的测试,然后创建test1,test2...等等对同一功能进行测试的不同文件。目前版本控制系统(VCS:Version Control System)主要可以分为:本地版本控制系统、集中化版本控制系统(CVCS)、分布式版本控制系统(DVCS)。
本地版本控制系统大多都是采用某种简单的数据库来记录文件的历次更新差异。其中比较流行的是(RCS:Revision Control System),不过本人没有使用过,这里就不说了。如下图是本地版本控制系统的工作示意图。
集中化版本控制系统(CVCS:Centralized Version Control System)是目前应用最广泛的。本地版本控制系统一个最大的问题就是无法在团队开发中使用,因为它无法协同开发者。CVCS是同过一台集中的服务器来进行开发者间的协作,服务器上保存了版本库中文件的所有修订历史,开发者可以通过服务器来进行代码的拉取和更新。最具有代表性的当属:Svn(Subversion)和CVS。目前公司内部使用的是Svn来进行代码的管理。集中化版本控制的优点就是刚刚所说的在团队开发中,方便协作,每个人都可以知道项目的开发进度,且对版本的管理更加方便。但和本地版本控制一样,CVCS也存在单点问题,一旦宕机谁也无法再拉取和更新代码,如果服务器磁盘坏了,又没有备份,就有可能导致所有版本的历史记录全部丢失。如下图是CVCS工作示意图:
为了解决CVCS的单点问题,分布式版本控制系统(DVCS:Distributed Version Control System)应运而生。对于DVCS,用户从服务器拉取的并不是最新版本库文件的快照,而是整个版本库的镜像。任何一台协同工作的服务器down掉后,都可以通过一个镜像进行恢复。此外每个客户端都可以看做是一台DVCS的服务器,可以作为协同工作的server。最具代表性的是:Git如下图为DVCS的工作示意图:
因为公司目前使用svn进行代码的管理,所以先讲一些svn的基本概念和使用。
Svn在团队开发中主要的工作流程如下:
开发者从svn服务器上checkout下代码,下面就是每天工作前update,下班后commit。常用命令操作如下:
svn checkout/co svn_address //拉取一个版本库到本地
svn update/up file or directory //更新最新版本到本地
svn commit/ci file or directory //提交更改到版本库
版本控制系统的核心任务是实现协作编辑和数据共享。对于集中式版本控制系统,在开发过程中最常发生的就是冲突问题,这是集中式带来的必然问题,该问题的描述如下:
当jack和rose两个人从版本库中拉下来同一份文件,然后分别修改了这个文件,接着jack先提交了自己修改的版本A’,提交结果是成功的,然后rose提交自己修改的版本A’’,结果就会提交失败。
Svn采用拷贝-修改-合并(Copy-Modify-Merge)版本控制模型来解决这种冲突问题。这是svn版本控制的核心。遇到上述问题,当rose提交自己的版本时,svn会提示文件A已经过期,并要求进行update,此时rose更新A,就会生产冲突,并生成如下文件:
此时rose可以根据上述文件,进行版本库和工作副本的合并,如果jack修改的部分和rose的并没有冲突,此时rose就可以将所有的修改合并到一起,然后提交。如果他们的修改有重叠的地方,那么rose和jack就要一起协商解决冲突,然后rose将合并后的提交。
在软件开发过程中,对于一个成熟的产品,代码的管理是很重要的,当然目前我还没有接触到。在通过svn进行版本管理过程中,分支是一个很基本的概念,它是版本控制一个重要组成部分。
这里要介绍svn的分支和标记。分支可以分为普通开发分支和主干分支。在svn版本库中我们看到最多的三个目录就是:trunk、branches、tags,这也是标准的做法,下面是svn标准建议每个部分的功能:
svn中没有用于建立分支和标记的特殊命令,而是使用便宜拷贝(类似linux中的硬链接),通过内部链接指向特定的版本树。创建分支/标记的命令如下:
svn copy svn://XXX/trunk svn://XXX/branches/branch_1
svn copy svn://XXX/branch_1 svn://XXX/tags/tags_release_1
Git安装后首先需要就是进行配置:
git config --global user.name "anonymalias" //用户名
git config --global user.email [email protected] // 邮箱
git config --global core.editor vim //文本编辑器
git config --global merge.tool vimdiff //差异化分析工具
用户名和邮箱是必须要配置的,因为每次提交时都会引用者两条信息。Git有时候需要调用文本编辑器来让用户输入一些信息。差异分析工具在解决冲突时使用。--global设置对当前用户所有操作生效,如果需要对特定项目进行设置,省略该选项,设定保存在当前项目目录的.git/config目录下。
Git库的初始化有两种方式:
git init
改命令会在当前目录生成.git目录,当前目录就可以进行版本管理了。可以使用如下命令进行版本管理:
git add file.c file.h
git add README
git commit -m 'initial project version
git clone https://github.com/anonymalias/test.git
这里git使用clone命令来完成项目的拉取,和svn的checkout不同。git会将远程仓库中的项目的所有数据都克隆到本地,和svn拉取文件快照有很大差别。
所有版本库目录下面的文件都可以分为两类:tracked(已跟踪)和untracked(未跟踪),在git下,tracked的文件可以分为:未修改、已修改、已暂存。和svn版本管理不同的是,git对于修改的tracked文件,要先暂存到暂存区(staged area),然后再提交到分支中。下图是git版本中文件状态转换图:
1.向版本库添加跟踪文件
git add file
git commit -m 'initial project version
2.提交修改的文件
和1的操作是一样的,要先通过add命令将修改暂存到暂存区,然后提交到版本库中。
3.移除文件
git rm file
git commit -m 'initial project version
4.版本状态查看
git status
5.分支的创建,切换,合并
git branch //查看当前版本库的所有分支,带*的是当前分支
git branch b1 //创建新分支b1,从当前分支而来,对于git只是创建一个分支指针
git checkout b1 //切换到分支b1,
git checkout -b b1 //等同于上面两条命令,创建分支并进行切换
git merge b1 //将分支b1合并到当前分支
6.分支的推送和拉取
这里首先要知道远程分支(remote branch)的概念。remote分支是对远程仓库状态的索引。我们通过(远程仓库名)/(分支名)的形式表示远程分支。远程分支的产生过程如下:
我们从远程服务器clone一个版本库,git 会自动为我们将远程仓库命名为origin,并下载其中所有的数据,建立一个指向它的 master 分支的指针,在本地命名为origin/master,但我们无法在本地更改其数据。接着,git会在origin/maste分支相同的位置,建立一个本地master 分支,我们的工作都是基于本地的master分支进行的。如下图:
当我们需要拉取远程仓库最新的版本时如下进行如下操作:
git fetch origin
该命令首先找到 origin 对应远程服务器的地址,然后更新最新的数据到本地origin版本库,然后把 origin/master 的指针移到它最新的位置。
git pull
pull命令相对于fetch命令的区别就是:它拉取最新的分支后,会合并到本地的分支。
下面的命令是将某个分支推送到远程操作上。
git push (远程仓库名) (分支名)
未完,带修改添加...
Created Date: 2014-06-28
Last Modified Date: 2014-06-28
Finish