CVS/SVN/GIT

一.CVS

(1)概念

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

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

(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正确使用步骤

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

二.SVN

(1)概念

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

     SVN的版本库可以通过网络访问,从而使用户可以在不同的电脑上操作。允许用户在各自的空间里修改和管理同一组数据,修改不再是单线进行(一个一个进行)。开发速度大大提高。此外,所有的工作都已版本化,不必担心由于错位的更改而影响软件质量,如果出现不正确的更改,只要撤销那一次更改操作。

(2)工作流程

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

优点
1、管理方便,逻辑明确,符合一般人思维习惯。
2、易于管理,集中式服务器更能保证安全性。
3、代码一致性非常高。
4、适合开发人数不多的项目开发。
5、大部分软件配置管理的大学教材都是使用svn和vss。

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

(3)常用命令

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

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

简写:svn co

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

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

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

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

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

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

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

8、查看日志
svn log path

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

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

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

12、SVN 帮助
svn help
svn help ci

13、版本库下的文件和目录列表
svn list path 显示path目录下的所有属于版本库的文件和目录简写:svn ls

14、创建纳入版本控制下的新目录

svn mkdir 创建纳入版本控制下的新目录。


16、代码库URL变更

svn switch (sw): 更新工作副本至不同的URL。

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

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

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

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

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

 

三.Git

(1)概念

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

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

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

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

暂缓区:英文名index 一般存放在.git目录下的index文件中,所以我们把暂存区有时也叫索引(index)。

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

三者之间的关系如下:

213449_W4Wq_3701483.jpg

图中左侧为工作区,右侧为版本库。在版本库中标记为 "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.修改完成后,如果发现错误,可以撤回提交再次修改并提交

212456_5Ht0_3701483.png

(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)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/u/3701483/blog/1546564

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值