分布式版本控制系统

来源:互联网 发布:nginx限制上传目录 编辑:程序博客网 时间:2024/04/28 17:47

分布式版本控制系统

——Mercurial

一、 分布式版本控制系统介绍

(1)CVCSDVCS   

Centralized Version Control Systems集中式版本控制系统

Distributed Version Control Systems 分布式版本控制系统

分布式版本控制 (DVCS) 是一种不需要中心服务器的管理文件版本的方法,但是它也可以使用中心服务器。更改可以被合并到 DVCS 的任何其他用户的系统中,因此可以实现非常灵活的工作流。DVCS 的两个主要优点是:它比集中的版本控制更灵活,因为它除了支持传统的(集中式)工作流,还支持其他各种工作流;它比集中式服务器快得多,因为大多数操作在客户机本地进行,而不需要网络操作。

在 DVCS 和集中式版本控制系统之间有三个关键差异。第一个差异是,DVCS 通过本地提交支持离线工作,这是由 DVCS 的操作方式决定的。这与集中式版本控制完全不同,集中式版本控制要求通过到中心服务器的连接执行所有操作。这种灵活性让开发人员在飞机上也能够像在办公室中一样轻松地工作,可以一次又一次地进行提交。 

第二个差异是 DVCS 比集中式系统更灵活,因为 DVCS 支持许多不同类型的工作流,从传统的集中式工作流到纯粹的特殊工作流,再到特殊工作流和集中式工作流的组合。这种灵活性允许通过电子邮件、对等网络和开发团队喜欢的任何方式进行开发。 

第三个差异是 DVCS 比集中式版本控制系统快得多,因为大多数操作在客户机上进行,速度非常快。另外,在需要进行推(push )操作(与另一个节点通信)时,速度也更快,因为两个客户机机器上都有完整的元数据。速度差异相当显著,根据使用本地存储库还是网络存储库,DVCS 比 Subversion 快大约 3-10 倍。

(2)分布式版本控制工作流

Partner 工作流。按照 Partner 工作流,一个开发人员启动一个项目,然后进行分支。然后,在不同开发人员工作的分支之间来回合并更改。

通过本地提交使用集中式服务器。在这种工作流中,开发人员的工作方式与使用集中式 Subversion 存储库时非常相似,但是他们进行本地提交,然后把最终更改推到集中式服务器。这种工作流有许多变体,包括与 Partner 工作流结合使用。重要的是,可以采用许多种工作方式,通过使用 DVCS,可以灵活地选择最适合自己的工作方式。

二、 Mercurial - 分布式版本控制系统

(1) Mercurial 简介

Mercurial 是一种轻量级分布式版本控制系统,采用 Python 语言实现,易于学习和使用,扩展性强。其是基于 GNU General Public License (GPL) 授权的开源项目。相对于传统的集中式 Subversion版本控制,具有如下优点:

更轻松的管理。传统的版本控制系统使用集中式的 repository,一些和 repository相关的管理就只能由管理员一个人进行。由于采用了分布式的模型,Mercurial 中就没有这样的困扰,每个用户管理自己的 repository,管理员只需协调同步这些repository。 

更健壮的系统。分布式系统比集中式的单服务器系统更健壮,单服务器系统一旦服务器出现问题整个系统就不能运行了,分布式系统通常不会因为一两个节点而受到影响。 

对网络的依赖性更低。由于同步可以放在任意时刻进行,Mercurial 甚至可以离线进行管理,只需在有网络连接时同步。

(2) repository仓库

版本控制系统中的 repository 就像一个仓库一样,用来存储被管理的数据文件,包含数据文件的不同版本。传统的版本控制系统中,这样的repository 是集中式的。除了这样一个集中式的 repository 之外,每个用户会有一份自己的工作版本拷贝。用户通过命令同步自己的拷贝和集中式的repository

分布式版本控制系统中的 repository 则采用的是对等网络式的方式。传统集中式的管理中,只有一份 repository,其他的只是工作拷贝,不包含额外的版本。分布式的管理当中,每个用户所持有的都是一个真实的 repository,当中存储有不同的版本信息和维护一个 repository 的必要的辅助元数据。这样一个对等工作模式当中,用户通过交换下文即将提到的 changeset 来完成同步。

这样做的一些优点在于,工作的并行度将大大的提高。每个用户都可以带着这样的repository,从这里他可以把当前的工作拷贝切换到 repository 里面存储的任何一个版本。这个版本可以是之前正在工作的版本,现在需要合并进一些别人的意见,也可以是用户私有的一个版本,当前正在做很多前瞻性的工作,还没有能同步给其他用户使用。也同样是因为这样的模式,每个用户可以任意把自己的 repository 当中的一个版本交换给其他用户,而不需要对自己手头正在工作的版本进行回退。下图是这样一个灵活的工作模式的演示。

(3) Mercurial 里的元素

Revision

在使用 Mercurial 的系统中每个改动隔离在各自的 repository 里,既避免把不相关的代码混杂起来, 又便于一个接一个的测试每一部分工作,用户做的每个改动称为一个 revision。一般会有一个所有用户都可以访问得到的 repository 保存了项目的“主要”版本,工作repository 是用户自己做事情的地方,实现新的特性,修改漏洞,重构,实验等,当完成改变后,你可以 push 到共用的 repository中,即完成了一个 revision

Changeset

一个或多个文件的改变集合在一起形成一个逻辑单元,称为 changeset。每一个 changeset由两部分内容描述,版本号和 changeset 标识,例如:

冒号前面的数字代表版本号,它用来标识本地 changeset。这个版本号只有在用户的本地repository 中才有意义。冒号后面的那个很长的十六进制串是 changeset标识它是确定changeset的全局唯一标识符在所有包含这个 changese 的 repository 中都相同。多个用户之间讨论changeset,一般使用这个 changeset 标识,而不是上面说的版本号,因为完全有可能每个用户的 repository 中同样的 changeset 版本号不同。

Head

Head 表示 repository 中每个分支最新的 revision,通常在合并几个分支时会用到这个概念。

Tip

Tip 是最新的一个 changeset 的版本号的一个别名。在命令中任何使用版本号的地方都可以使用 tip 来代替最新的 changeset的版本号。Tip在各个repository中是不同的,同时一个repository 中只有一个 tip

Log

Log 命令按时间顺序从近到远的记录着在 repository 中发生的每一次事件。可以通过指定-v诊断输出选项来获得更多更详细的历史信息,或者指定—debug选项来获得历史信息中的一切细节。

三、 MercurialWindowsLinux下的安装和使用

(1) MercurialWindows下的安装和使用

① 下载TortoiseHg-0.7.6-hg-1.2.1.exe可执行程序,直接安装即可,也可以从源代码编译安装,具体参看

http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall

② 项目负责人创建一个原始版本并做设置

      

③ 创建本地repository

④创建本地repository后的仓库中的文件(原仓库中为空文件夹)

⑤向本地repository添加文件

⑥添加文件后向本地repository提交

提交后本地repository中文件入下所示:

⑦创建一个精确的克隆版本,放到一个其他组员可以访问到的地方,供其他组员分享使用

 

⑧其他组员访问公共站点进行更新

pullpush的使用,在DVCS host中添加一空的zip文件,在DVCS client1中添加一个空的html文件及bmp文件

和本地自己的repository库合并

我们从DCVS host repository pull更新得到blank.zip。下面说明push的使用方法

要注意以上两个参数的设置

⑩其他功能

(2) MercurialLinux下安装使用(VMware CentOS5.3,VMware采用hostonly方式和宿主机通信

① 下载mercurial-1.2.1.tar.gz源码 下载地址:http://mercurial.selenic.com/release/

② tar zxvf mercurial-1.2.1.tar.gz 说明阴影部分为bash shell root用户所用命令

# cd mercurial-1.2.1

# python setup.py install --force --home=$HOME

设置PYTHONPATH

#vi ~/.bash_profile

在该文件中添加export PYTHONPATH=$PATH:$HOME/root/lib/python 注意橙色部分为你自己安装时的路径

#source ~/.bash_profile

安装好后

# hg 

Mercurial Distributed SCM

basic commands:

 add        add the specified files on the next commit

 annotate   show changeset information per file line

 clone      make a copy of an existing repository

 commit     commit the specified files or all outstanding changes

 diff       diff repository (or selected files)

 export     dump the header and diffs for one or more changesets

 init       create a new repository in the given directory

 log        show revision history of entire repository or files

 (...)

③ 克隆仓库

# hg clone http://192.168.0.1:8000 my-hello

requesting all changes

adding changesets

adding manifests

adding file changes

added 5 changesets with 8 changes to 7 files

updating working directory

7 files updated, 0 files merged, 0 files removed, 0 files unresolved

在当前目录下会有一个my-hello目录

#cd my-hello

#ls

blank.rar  blank.zip  hello.c  hello.h  helloWorld.txt  readme.txt

出现的就是我们在WindowsDCVS host文件夹中的内容

④ 变更文件

hg clone http://192.168.0.1:8000 my-hello-new-output

ls

anaconda-ks.cfg  Desktop             lab       my-hello-new-output

bin              install.log         lib

C++              install.log.syslog  my-hello

# cd my-hello-new-output

#vi hello.c

 #include <stdio.h>

int main()

{

  printf("Hello,Mercurial!");

  printf("sure am glad I'm using Mercurial!");  /*此行为添加的*/

  return 0;

}

hg status

M hello.c  /*以 开头的行意思就是hello.c文件修改过了*/

使用 diff 命令我们可以检查文件实际的改变:

# hg diff

diff -r 8f09d6982f89 hello.c

--- a/hello.c   Thu Jul 02 20:08:11 2009 +0800

+++ b/hello.c   Thu Jul 02 21:08:21 2009 +0800

@@ -2,5 +2,6 @@

 int main()

 {

   printf("Hello,Mercurial!");

+  printf("sure am glad I'm using Mercurial!");

   return 0;

 }

万一我们希望放弃我们的变更并重新开始,我们可以用revert命令来恢复到我们没有更改的状态。

# hg revert

⑤ 接下来我们要提交我们创建的变更集

# hg commit

HG: Enter commit message.  Lines beginning with 'HG:' are removed.

HG: --

HG: user: root@xmu.leeiee

HG: branch 'default'

HG: changed hello.c

为了提交变更集,我们必须描述它的原因,我们加入注释

我们现在可以为我们的新工作检查变更的历史

# hg log

changeset:   5:0660ed208d40

tag:         tip

user:        root@xmu.leeiee

date:        Thu Jul 02 21:15:33 2009 +0800

summary:     Express great joy at existence of Mercurial

⑥ 与别的仓库分享改变

   我们在my-hello-new-output 仓库中创建了一个变更集。现在我们希望在其它地方扩展那个变化。

   #cd my-hello-share

#hg -q tip

4:8f09d6982f89

#cd ../my-hello-new-output/

#hg -q tip

5:0660ed208d40

the Tip 在各个仓库中是不同的。让我们回到 my-hello-share 并在那里扩展我们的新变更集。要达到这个目的,我们用 pull 命令,这个命令所有在别的仓库中有而在本仓库中没有的 ChangeSet 从别的仓库 Pull 到本仓库。

#cd ../my-hello-share

# hg pull ../my-hello-new-output

pulling from ../my-hello-new-output

searching for changes

adding changesets

adding manifests

adding file changes

added 1 changesets with 1 changes to 1 files

(run 'hg update' to get a working copy)

最近一行输出是重要的。在 Pull 后,缺省情况下 Mercurial 不更新工作目录。这意味着虽然 Repository 现在有变更集, 但在工作目录中的 hello.c 文件仍然是Pull 之前老的内容。

我们可以用以下Mercurial的提醒来 Update 这个文件 (也包括所有其它 Pull 时改变的文件)。

#hg update

1 files updated, 0 files merged, 0 files removed, 0 files unresolved

#hg -q tip

5:0660ed208d40

现在my-hello-sharemy-hello-new-output有相同的内容和版本历史记录  

⑦ 通过网络分享改变

   # hg incoming http://192.168.0.1:8000

comparing with http://192.168.0.1:8000

searching for changes

changeset:   7:46bc915ccd2b

parent:      2:1ca713fd149c

user:        leeiee

date:        Thu Jul 02 19:11:08 2009 +0800

summary:     a file include  bmp and html

changeset:   8:ba5a08ead13e

parent:      7:46bc915ccd2b

parent:      3:45394e4035a4

user:        leeiee

date:        Thu Jul 02 19:32:54 2009 +0800

summary:     merge

#hg pull http://192.168.0.1:8000

pulling from http://192.168.0.1:8000

searching for changes

adding changesets

adding manifests

adding file changes

added 7 changesets with 3 changes to 5 files (+1 heads)

(run 'hg heads' to see heads, 'hg merge' to merge)

原创粉丝点击