求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
 
   
分享到
DVCS分布式的版本控制图解说明
 

作者:yslin , 发布于2012-6-21

 

传统的版本控制辅助档案的备份,追踪与同步. 分布式的版本控制让变更的分享简单容易. 如果你做的对, 你可以鱼与熊掌兼得: 简单的合并同时并可以集中版本发布.

要分布式的吗? 一般的版本控制到底发生什么问题?

没有问题 — 如果你想快速回忆的话请参考VCS版本控制视觉指引 . 当然, 有些人可能会嘲笑你还在用”古老”的系统. 但在我看来仍然是OK的: 对于任何项目来说有用版本控制系统总是正向的一步. 集中的版本控制系统在1970年代出现, 当初程式设计者有了精简型终端机(thin clients)但同时也欣羨又大又贵又快速的”big iron” mainframes(谁能不被当时风行的大小通吃8bits到1 byte的机器吸引呢?)

集中管理是简单的概念, 很自然是第一步想到的:让每个人到同一个地方签入签出, 就像集中到某个图书馆的书本上注记一样.

如此的做法对于备份,复原和同步行得通, 不过对变更的合并与分支却不太行. 当项目成长时, 通常会想将功能切割, 独立开发与测试, 再逐步将变更并入主开发线. 实际做时, 分支就很麻烦, 新的功能可能要做庞大的签入, 如果中间有任何差错, 变更变得很难管理也很难做问题排解. 当然, 集中控管的系统也总有”可能”做合并, 但并不容易: 你需要亲自确实追踪合并的动作与内容, 以避免同样的变更被做两次. 分布式的版本控制系统让分支与合并无痛执行, 因为这是此类系统的长处. (译注: SVN支持Merge Tracking后就可以避免同样的变更会合并两次以上的问题)

请看一些图解

别的教学多是严肃的命令列指令, 在此提供您视觉化的说明. 让你回想一下运用典型集中控管的版本库的状况:

每个人与主开发线同步也将档案签入主开发线: Sue加入soup, Joe加入juice, Eve加入eggs. Sue的变更必须先签入主开发线才会被其他人看到. 的确, 理论上, Sue可以另开一个新的分支让其他人测试她的变更, 可是在一般的版本控制系统(VCS)如此做很麻烦.

分布式版本控制系统(DVCS)

依分布式模式, 每位开发者有他们自己的版本库. Sue的变动存在她个人端计算机的版本库,她可以决定是否要跟Joe或Eve分享:

不过是否有可能造成像无头的圆环一样循环呢? 不会的, 如果想要的话, 每个人可以将他的变动推(push)给同一个版本库, 存疑地, 就像上述集中的模式一般. 此人为的版本库(franken-repo)包含了Sue, Joe和Eve的变动.

我希望分布式版本控制DVC(distributed version control)可以有不同的名称, 如 “独立的(independent)”, “联合的(federated)” 或 “点对点的(peer-to-peer)”. 此字 “分散”让人联想到分布式运算, 工作被分派给一群机器(如寻找外星智慧讯号的 SETI@home {可参考SETI@home台湾网站} 或做 蛋白质摺叠分析Protein folding).

而DVCS并不像Seti@home: 每一端(node)是各自独立的且是否分享由各端自我决定(在Seti, 你必须回覆你的结果)

5分钟说明主要观念

此给你基本概念; 如果你有兴趣, 可参考相关patch theory的说明书 .

核心概念

  • 集中式版本控制聚焦于同步,追溯(tracking), 和备份档案.
  • 分布式版本控制聚焦于变动分享; 每一变更有其 全域唯一辨识码(guid-global unique id)或unique id.
  • 记录/下载以及采用一个变更被视为分别的步骤 (在集中式系统, 此三者同时发生).
  • 分布式系统没有强制的架构. 你可以建立”中央管理”区或让个人保持各自端运作.

新术语

  • 推(push): 将变更送给其他的版本库 (应该需要其它版本库拥有者的允许)
  • 拉(pull): 从另一版本库下载同步档案变更

关键优势

  • 每人都有其本地端的沙盒(local sandbox). 你可以在自己的工作计算机上修改或回覆前版, 不需要大量的签入. 你自己的工作记录都累积存在自己的版本库.
  • 可离线工作. 你只有当你想分享变更时才需要上线. 否则你可随你高兴一直在自己的工作计算机上独立作业, 签入或复原, 没有所谓”伺服器”当掉或在飞机上的问题.
  • 速度很快. 差异(diff), 提交源码与变更回复都在本地端即可完成. 没有因网路或伺服器不稳而必须用一年前开发版本的问题.
  • 可妥善做变动的处理. DVCS针对分享的变更做建置. 每个变更都有其独一无二的辨识码(GUID)以方便追踪.
  • 分支与合并很容易. 因为每一开发人员”有自己的分支”, 每一分享的变动就像交换整合. 但独一无二的辨识码(GUID)让自动合并变更与避免重复合并动作变的简单容易.
  • 较少的管理. DVCS很容易执行; 没有所谓的“总在运作的”伺服器软体需要安装. 此外, DVCS也不太需要你去”加”新的使用者; 你只是去捡选你想从那里拉(pull)版本库的URLs. 这样可以避免大型项目中令人头痛的政治性问题.

关键劣势

  • 仍需要备份. 有个说法是你的“备份”就是其他人有你变更资料的终端机信息. 我无法认同—如果这些其他人终端机资料并没有采用你所有的变更呢? 或是当你变更的时候他们都不在线上? 用DVCS, 你仍希望可以有台机器让你push所有的变更到那里保存“以防万一”. (在Subversion, 你有一台随时待命的机器做主要的资料贮存库, 建议您在DVCS也做一样的事). (译注: 如有兴趣了解架设与管理DVCS服务器的工具, 欢迎参考CodeBeamer+Mercurial实务操作手册 与 CodeBeamer+Git实务操作手册)
  • 没有所谓的“最近的版本”存在. 如果没有集中地, 你无法马上知道是否要到Sue, Joe或Eve那取得最近变更的版本(version). 再者, 一个中央集中地才可帮助大家清晰知道最近的”稳定版本”为何.
  • 没有真正的修订版号码(revision numbers). 每一版本库有依变更做出的修订版号码. 和传统的版本库不同的方法,人们依变更的修订号码做沟通: “请问你有变更号码 fa33e7b? ” (记住, 这ID是一个不好看的GUID总体唯一辨识码). 还好, 你可以用有意义的名字贴标你发布的版本.

Mercurial 快速上手(Quickstart)

Mercurial速度很快,是个简易的DVCS. 暱称是hg, 就像水银(Mercury)元素一样.

一旦Mercurial已经初始化一个目录, 看起来将如下:

你将有:

  • 一个工作拷贝(working copy). 你正在编辑的档案群.
  • 一个版本库. 一个目录(Mercurial的.hg)包含所有的补钉(patches)以及可转译资料(metadat:comments, guids, dates, etc.). 因为没有集中的伺服器, 所以这些资料都放在你这里.

在我们的分布式案例, Sue, Joe和Eve有他们各自的版本库, 储存他们不相干的修订版历史资料(revision histories).

理解更新(Updates)与合并(Merging)

在研究DVCS时有几项让我有些混淆.

第一, 有几步将造成更新(updates)

  • 取得变更到版本库:推(pushing) 或 拉(pulling)
  • 采用变更到档案中:更新(update) 或 合并(merging)
  • 储存新版:签入/提交源码(commit)

第二, 依据变更, 你可以更新或合并:

  • 当无模糊地带时,更新(Updates)发生. 譬如, 我将变更拉(pull)到一直以来都是你在编辑的档案. 因没有重叠的变更,档案将跳到最近的修订版(revision).
  • 当我们的变更发生冲突时,就有必要合并(Merge). 如果我们两个都去编辑档案,最后会变成两个”分支”, 类似平行宇宙(alternate universes-多种假设同时发展的各个故事)的样子. 有个我修改的世界, 也有个你修改的世界. 在此例, 我们可能想要合并成一个单一的宇宙.

我仍在整理DVCS到底可多容易的产生分支与摺叠分支:

在此案,因为 (+Soup) 和 (+Juice) 为同一个母项(parent-仅一个 “Milk”的列表)的变更, 有必要做合并(merge). 经过Joe合并档案后, Sue可以做一般的 “pull和update” 即可获得Joe已合并的结果. 她不需要亲自做合并的动作. .

在Mercuril, 你可如下执行:

是的, “pull-merge-commit” 周期蛮长的. 幸运地, Mercurial有整合多指令(commands)为单一的捷径. 虽说看起来好像蛮复杂的, 但仍比在Subversion手动合并简单多了.

大多数的合并是自动完成的. 当发生冲突时, 一般可以很快被解决. Mercurial持续追踪每一变更的母/子关系(我们的合并列表有两个母项), 与”最新版(heads)”或每一分支的最近变动. 在合并前我们有两个heads;之后, 一个.

组织一分布式项目

此为一种组织方式:

Sue, Joe和Eve将变更加入一共同的分支. 他们可以跟任一人交易补丁(patches)来做”兄弟建置(buddy builds)”:嘿 老兄, 请问要试试这些补丁吗? 在推给实验分支(experimental branch)前,我需要看看此是否可行.

然后, 经维护守门员在看过,将实验分支的变更拉到稳定的分支(stable branch), 此有最近的版本. 分布式的版本控制系统(DCVS)帮助每一变更独立进行, 但也提供集中系统所有的”单一来源(single source)”. 有多种开发的模式可用, 如”pull only”,此只有维护守门员决定是否要从别人拿取变更资料, Linux的开发采用此种,或”shared push”, 此和集中管理的系统作业模式很类似. DVCS让您弹性选择要采用哪种方法来维护您的项目.

相关文章

每日构建解决方案
如何制定有效的配置管理流程
配置管理主要活动及实现方法
构建管理入门
相关文档

配置管理流程
配置管理白皮书
CM09_C配置管理标准
使用SVN进行版本控制
相关课程

配置管理实践
配置管理方法、工具与应用
多层次集成配置管理
产品发布管理
   


软件配置管理的问题、目的
软件配置管理规范
CQWeb 7.1性能测试与调优指南
为什么需要使用ClearCase
ClearCase与RTC的集成
利用ClearQuest 进行测试管理
更多...   


产品发布管理
配置管理方法、实践、工具
多层次集成配置管理
使用CC与CQ进行项目实践
CVS与配置管理
Subversion管理员


配置管理实践(从组织级到项目级)
通号院 配置管理规范与应用
配置管理日构建及持续集成
丹佛斯 ClearCase与配置管理
中国移动 软件配置管理
中国银行 软件配置管理
天津华翼蓝天科技 配置管理与Pvcs