CVS/SVN/GIT

一.CVS

(1)概念

CVS(Concurrent Versions System)即版本控制系统,是一个C/S(Client/Service)系统。多个开发人员经过一个中心版本控制系统来记录文件版本,从而达到保证文件同步的目的,工做模式:php

     CVS服务器(文件版本库)
     /     |       \
     (版 本 同 步)
   /       |         \
开发者1  开发者2   开发者3git

(2)功能介绍

a、 代码统一管理,保存全部代码文件更改的历史记录。对代码进行集中统一管理,能够方便查看新增或删除的文件,可以跟踪全部代码改动痕迹。能够随意恢复到之前任意一个历史版本。并避免了由于版本不一样引入的深层BUG。
b、 完善的冲突解决方案,能够方便的解决文件冲突问题,而不须要借助其它的文件比较工具和手工的粘贴复制。
c、 代码权限的管理。能够为不一样的用户设置不一样的权限。能够设置访问用户的密码、只读、修改等权限,并且经过CVS ROOT目录下的脚本,提供了相应功能扩充的接口,不但能够完成精细的权限控制,还能完成更加个性化的功能。
d、 支持方便的版本发布和分支功能。数据库

(3)经常使用术语

资源库(Repository)
CVS的资源库存储所有的版本控制下的文件copy,一般不允许直接访问,只能经过cvs命令,得到一份本地copy,改动后再check in(commit)回资源库。而资源库一般为与工做目录分离的。CVS经过多种方式访问资源库。每种方法有不一样目录表示形式。
版本(Revision)
每个文件的各个版本都不相同,形如1.1, 1.2.1,通常1.1是该文件的第一个revision,后面的一个将自动增长最右面的一个整数,好比1.2, 1.3, 1.4...有时候会出现1.3.2.2,缘由见后。revision老是偶数个数字。通常状况下将revision看做时CVS本身内部的一个编号,而tag则能够标志用户的特定信息。
标签(Tag)
用符号化的表示方法标志文件特定revision的信息。一般不须要对某一个孤立的文件做tag,而是对全部文件同时做一个tag,之后用户能够仅向特定tag的文件提交或者checkout。另一个做用是在发布软件的时候表示哪些文件及其哪一个版本是可用的;各文件不一样revision能够包括在一个tag中。若是命名一个已存在的tag默认将不会覆盖原来的;
分支(Branch)
当用户修改一个branch时不会对另外的branch产生任何影响。能够在适当的时候经过合并的方法将两个版本合起来;branch老是在当前revision后面加上一个偶数整数(从2开始,到0结束),因此branch老是奇数个数字,好比1.2后面branch为1.2.2,该分支下revision可能为1.2.2.1,1.2.2.2,...
冲突(Conflct)
彻底是纯文本的冲突,不包含逻辑上的矛盾。通常是一份文件,A作了改动,B在A提交以前也作了改动,这样最后谁commit就会出现冲突,须要手工解决冲突再提交。缓存

(4)经常使用命令

Check Out(检出)
把源文件从cvs源代码仓库中取出,缺省的版本是最新的版本,你也能够选择指定的版本。在每次更改源代码以前,须要Check Out最新的版本,再起基础之上对源代码进行修改。将代码目录checkout到指定目录下,全部文件都是read-write。
Check In(检入)
把源代码加入到cvs源代码仓库中,每个添加进代码库中的文件的版本是 1.1。之后每次修改文件从新ci之后,此文件的版本递增为1.2 ,1.3.……。在每次对源代码修改以后,须要Check In,提交最新版本的源代码。
Synchronize with Repository(与资源库同步,简称同步)
使本地更改与资源库同步,它会列出本地和资源库之间不一样的全部文件。
Add to Version Control
将新的文件加入到版本控制之中。
Add to .cvsIgnore
将文件设置到版本控制以外,这样该文件或目录中的文件的更改在CVS中不可见,即便同步也没法发现。安全

(5)CVS正确使用步骤

1、 同步(Synchronize)
就是将本地更改与服务器同步,同步以后能够清晰的看到上一捡出(Check Out)版本以后本地、服务器上的最新改动。这是很是有用的,特别是敏捷开发,强调集体拥有代码。有了同步功能,你能够全局把握项目的代码,能够很方便的跟踪公共模块代码的任何改动。
同步以后,它有四种Mode能够选择,从左到右分别为:
Incoming Mode:表示修改是来自服务器,对应于更新(update)操做。
Outgoing Mode:表示修改是来自本地,对应提交(commit)操做。
Incoming/ Outgoing Mode:本地和服务器修改都在该模式(Mode)中显示。
Conflicts Mode:显示本地和服务器修改的冲突文件。
2、 更新(update)
比较简单,选择Incoming Mode,再选中要更新的文件,右键选择update操做。
3、 解决冲突并合并(solve conflct and merge)
若是有冲突文件,冲突文件不能更新。你必须先解决冲突再操做。选中冲突的文件,再点右键选择"Open in Compare Editor",用比较工具打开该文件。以下图:
4、 提交(commit)
更新服务器代码,解决冲突以后,首先要查看本地文件修改以后是否有错误。若是有,固然首先解决错误,再提交。服务器

二.SVN

(1)概念

      SVN(Subversion),是一个开源的版本控制系统,较于CVS,采用了分支管理系统,设计目标就是取代CVS。文件保存在中央仓库,除了能记住文件和目录的每次修改外,版本库就像普通的文件服务器,说的简单一点SVN就是用于多我的共同开发同一个项目,共用资源的目的。管理者能够将文件恢复到过去的版本,而且经过检查历史知道谁对数据作了哪些修改。能够看做是“时间机器”。网络

     SVN的版本库能够经过网络访问,从而使用户能够在不一样的电脑上操做。容许用户在各自的空间里修改和管理同一组数据,修改再也不是单线进行(一个一个进行)。开发速度大大提升。此外,全部的工做都已版本化,没必要担忧因为错位的更改而影响软件质量,若是出现不正确的更改,只要撤销那一次更改操做。app

(2)工做流程

SVN集中式代码管理的核心是服务器,全部开发者在开始新一天的工做以前必须从服务器获取代码,而后开发,最后解决冲突,提交。全部的版本信息都放在服务器上。若是脱离了服务器,开发者基本上能够说是没法工做的。下面举例说明:
开始新一天的工做:
一、从服务器下载项目组最新代码。
二、进入本身的分支,进行工做,每隔一个小时向服务器本身的分支提交一次代码(不少人都有这个习惯。由于有时候本身对代码改来改去,最后又想还原到前一个小时的版本,或者看看前一个小时本身修改了哪些代码,就须要这样作了)。
三、下班时间快到了,把本身的分支合并到服务器主分支上,一天的工做完成,并反映给服务器。
这就是经典的svn工做流程,从流程上看,有很多缺点,但也有优势。编辑器

优势
一、管理方便,逻辑明确,符合通常人思惟习惯。
二、易于管理,集中式服务器更能保证安全性。
三、代码一致性很是高。
四、适合开发人数很少的项目开发。
五、大部分软件配置管理的大学教材都是使用svn和vss。分布式

缺点
一、服务器压力太大,数据库容量暴增。
二、若是不能链接到服务器上,基本上不能够工做,看上面第二步,若是服务器不能链接上,就不能提交,还原,对比等等。
三、不适合开源开发(开发人数很是很是多,可是Google app engine就是用svn的)。可是通常集中式管理的有很是明确的权限管理机制(例如分支访问限制),能够实现分层管理,从而很好的解决开发人数众多的问题。

(3)经常使用命令

1.将文件检出checkout到本地目录

svn checkout path(path是服务器上的目录)
简写:svn co

简写:svn co

二、往版本库中添加新的文件

svn add file
3.将改动的文件提交到版本库

svn commit -m “LogMessage” [-N] [--no-unlock] PATH(若是选择了保持锁,就使用–no-unlock开关)
简写:svn ci

四、加锁/解锁
svn lock -m “LockMessage” [--force] PATH
svn unlock PATH

五、更新到某个版本
svn update -r m path
简写:svn up

六、查看文件或者目录状态
1)svn status path(目录下的文件和子目录的状态,正常状态不显示)
2)svn status -v path(显示文件和子目录状态)
简写:svn st

七、删除文件
svn delete path -m “delete test fle”
简写:svn (del, remove, rm)

八、查看日志
svn log path

九、查看文件详细信息
svn info path

十、比较差别
svn diff path(将修改的文件与基础版本比较)
svn diff -r m:n path(对版本m和版本n比较差别)
简写:svn di

十一、将两个版本之间的差别合并到当前文件
svn merge -r m:n path

十二、SVN 帮助
svn help
svn help ci

1三、版本库下的文件和目录列表
svn list path 显示path目录下的全部属于版本库的文件和目录简写:svn ls

1四、建立归入版本控制下的新目录

svn mkdir 建立归入版本控制下的新目录。


1六、代码库URL变动

svn switch (sw): 更新工做副本至不一样的URL。

用法:
一、switch URL [PATH]
更新你的工做副本,映射到一个新的URL,其行为跟“svn update”很像,也会将 服务器上文件与本地文件合并。这是将工做副本对应到同一仓库中某个分支或者标记的方法。
二、switch --relocate FROM TO [PATH...]
改写工做副本的URL元数据,以反映单纯的URL上的改变。当仓库的根URL变更 (好比方案名或是主机名称变更),可是工做副本仍旧对映到同一仓库的同一目录时使用 这个命令更新工做副本与仓库的对应关系。

1七、解决冲突
svn resolved: 移除工做副本的目录或文件的“冲突”状态。
用法: resolved PATH...

注意: 本子命令不会依语法来解决冲突或是移除冲突标记;它只是移除冲突的相关文件,而后让 PATH 能够再次提交。

1八、输出指定文件或URL的内容。
svn cat 目标[@版本]...若是指定了版本,将从指定的版本开始查找。

svn cat -r PREV filename > filename (PREV 是上一版本,也能够写具体版本号,这样输出结果是能够提交的)

 

三.Git

(1)概念

Git是一款免费,开源的分布式版本控制系统,有效、高速的处理大小项目版本管理。

Git不只仅是版本控制系统,也是一个内容管理系统(CMS),工做管理系统。

Git工做区、暂缓区、和版本库概念

工做区:就是你在电脑里能看到的目录。

暂缓区:英文名index 通常存放在.git目录下的index文件中,因此咱们把暂存区有时也叫索引(index)。

版本库:工做区有一个隐藏目录.git 是Git的版本库。

三者之间的关系以下:

图中左侧为工做区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage, index),标记为 "master" 的是 master 分支所表明的目录树。

图中咱们能够看出此时 "HEAD" 实际是指向 master 分支的一个"游标"。因此图示的命令中出现 HEAD 的地方能够用 master 来替换。

图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下,里面包含了建立的各类对象及内容。

当对工做区修改(或新增)的文件执行 "git add" 命令时,暂存区的目录树被更新,同时工做区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。

当执行提交操做(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会作相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。

当执行 "git reset HEAD" 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,可是工做区不受影响。

当执行 "git rm --cached <file>" 命令时,会直接从暂存区删除文件,工做区则不作出改变。

当执行 "git checkout ." 或者 "git checkout -- <file>" 命令时,会用暂存区所有或指定的文件替换工做区的文件。这个操做很危险,会清除工做区中未添加到暂存区的改动。

当执行 "git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令时,会用 HEAD 指向的 master 分支中的所有或者部分文件替换暂存区和以及工做区中的文件。这个命令也是极具危险性的,由于不但会清除工做区中未提交的改动,也会清除暂存区中未提交的改动。

 

(2)工做流程

通常工做流程以下:

1.克隆Git 资源做为工做目录。

2.在克隆的资源上添加或修改文件

3.若是其余人修改了,能够更新资源

4.在提交前查看修改

5.提交修改

6.修改完成后,若是发现错误,能够撤回提交再次修改并提交

(3)建立仓库

git init 初始化一个Git 仓库,Git的不少命令都须要在Git的仓库里运行。

在执行git init 命令后,Git仓库会生成一个.git 目录,该目录包含了资源的全部元数据,其余的项目目录不变。

使用当前目录做为Git仓库:

git init (会生成一个.git 目录)

使用指定目录做为Git仓库

git init newrepo

初始化后,会在newrepo目录下出现一个名为.git的目录,全部Git 须要的数据和资源都存放在这个目录中。

若是当前目录下有好多个文件想要归入版本控制,须要先用git add 命令 告诉git 开始对这些文件进行跟踪,而后提交

git add a

git add b

git add c

git commit -m '初始化项目版本'

 

git clone

使用git clone 从现有Git 仓库中拷贝项目

git clone

若是须要克隆到指定的目录,可使用

git clone repo directory

repo:Git 仓库

directory:本地目录

 

获取与建立项目命令

git init

用git init 在目录中建立新的Git 仓库。是本地化的

在目录中执行git init ,就能够建立一个Git 仓库了。

如:

mkdir  newDir

cd  newDir/

git init

能够在项目中生成.git这个子目录,这就是Git仓库,全部关于项目的快照数据都存放在这里。

git  clone

使用git clone 拷贝一个Git 仓库到本地,能够查看或者进行修改。

git clone [url]

url 为复制的项目连接。

基本快照:

Gitd 工做就是建立和保存项目的快照及与以后的快照进行对比。

git add能够将该文件添加到缓存。

$ touch README

$ touch hello.php

$ ls README        hello.php

$ git status     -s ?? README ?? hello.php $

git touch 用于建立文件

git status -s 用于查看项目的当前状态。

git add hello.php  README

git add 命令用于添加文件

如今再次执行git status ,就能够看到这两个文件已经添加上去了。

$ git status -s

A README

A hello.php

$

新项目中,添加全部文件很广泛,可使用 git add .(中间有一个空格) 命令来添加当前项目的全部文件

git add .

再次使用git status -s 查看状态

$ git status -s
A  1.txt
A  2.txt
A  README
A  hello.txt
A  ssm

如今修改README文件:在README文件中添加 #Runoob Git测试字样,保存并退出。

再次执行git status -s

$ git status -s
A  1.txt
A  2.txt
AM README
A  hello.txt
A  ssm

AM状态的意思是,这个文件在咱们将它添加到缓存以后有改动,改动后咱们再执行git add命令将它添加到缓存中。

git add .

当咱们要讲修改的内容包含在即将提交的快照里面的时候,须要执行 git add 。

$ git status -s
A  1.txt
A  2.txt
A  README
A  hello.txt
A  ssm

git status 

git status能够查看在你上次提交以后是否有修改 git status -s 用于得到简短的结果输出。

git status on branch master

$ git status on branch master
On branch master

Initial commit

nothing to commit (create/copy files and use "git add" to track)

git diff

 git diff能够查看执行git status 的结果的详细信息。

git diff 命令显示已写入缓存与已修改但还没有写入缓存的改动的区别。 git diff 主要有两个使用场景:

还没有缓存的改动:git diff

查看已缓存的改动: git diff --cached

查看已缓存的与未缓存的全部改动:git diff HEAD

显示摘要而非整个diff git diff --stat

git status 显示上次提交更新后或者写入缓存的改动,而git diff 一行一行的显示这些改动具体是啥。

git commit

使用git add 命令将想要快照的内容写入缓存区,而执行git commit 是将缓存区内容添加到仓库中。

Git 为每个提交都记录名字和邮箱,因此第一步须要配置用户名和邮箱地址

$ git config --global user.name 'runoob'

$ git config --global user.email test@runoob.com

而后写入缓存,并提交对文件的全部改动。使用-m 选项在命令行中提供注释

$ git add hello.php

$ git status -s

A README A hello.php

$ $ git commit -m '第一次版本提交' [master (root-commit) d32cf1f] 第一次版本提交

2 files changed, 4 insertions(+)

create mode 100644 README

create mode 100644 hello.php

如今已近记录好快照,若是再执行git status

$ git status
On branch master
nothing to commit, working tree clean
咱们在最近一次提交后,没有作任何改动,是一个working directory clean 干净的工做目录

若是没有设置-m 选项,Git 会尝试打开一个编辑器以填写提交信息,若是Git 在你对他的配置中找不到信息,默认会打开Vim ,屏幕会这样。。

# Please enter the commit message for your changes. Lines starting

# with '#' will be ignored, and an empty message aborts the commit.

# On branch master # Changes to be committed:

# (use "git reset HEAD <file>..." to unstage)

#

# modified: hello.php

# ~ ~ ".git/COMMIT_EDITMSG" 9L, 257C

若是以为git add 提交缓存的流程太繁琐,Git 可使用 -a 选项跳过这一步,

git commit -a

$ git commit -a
On branch master
nothing to commit, working tree clean
 

git reset HEAD

git reset HEAD命令用于取消已缓存内容。

git  reset HEAD 能够取消以前git add 添加,但不但愿包含在下一提交快照中的缓存。

 

git rm

git rm 会将条目从缓存区移出,。

git rm file 会将文件从缓存区和硬盘中(工做目录)删除。

 

git mv

git mv命令用于移动或者重命名一个文件,目录,软链接。

 

GIT分支管理

几乎每种版本控制系统都以某种形式支持分支。使用分支意味着能够从开发主线上分离开来,而后在不影响主线的同时继续工做。

Git 的优势就在于它的分支模型。

建立分支:git branch(branchName)

切换分支:git checkout(branchName)

当切换分支的时候,Git 会用该分支的最后提交的快照替换你电脑上的工做目录的内容,因此多个分支不须要多个目录。

合并分支: git merge

能够屡次合并到统一分支,也能够选择在合并后直接删除被并入的分支。

Git分支管理:

列出分支:

git branch

没有参数时,git branch 会列出你在本地的分支

$ git branch

* master

意思是:有一个叫master的分支,而且该分支是当前分支,当执行git init 的时候,缺省状况下Git 就会建立master 分支,可使用git branch (branchName) 建立一个新的分支。

git checkout -b(branchName)

git checkout -b 命令用来建立新分支并当即切换到该分支下,从而在该分支进行操做

删除分支

git branch -d(branchname)

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息