®内容安排SCM简介问题空间并行Release的开发:如何在开发Release2.0的同时维护Release1.0出差与异地工作:源代码版本失控,或者控制手段过于复杂相似项目/产品的管理:每个项目都在低水平重复公共代码的管理:项目间彼此影响基本原理与方法版本合并:矩形模型任务单元/活动,及其增强直接工作流与间接工作流组件,及其本质不同商用/免费工具软件的支持情况内容安排(2)解空间任务单元在并行Release之间的迁移对离线工作的支持和管理分布式开发场景和多重集成的实现用任务单元集来表达相似项目间的差异内部项目/产品更多听众提出更多SCM棘手问题,逐一讨论®是关于……X-AxisConfigurationGeographySpaceItemandStructureY-AxisChangeHistoryTimeTask/Activity定义[IEEE-STD-610.1990]Adisciplineapplyingtechnicalandadministrativedirectionandsurveillancetoidentifyanddocumentthefunctionalandphysicalcharacteristicsofaconfigurationitem,controlchangestothosecharacteristics,recordandreportchangeprocessingandimplementationstatus,andverifycompliancewithspecifiedrequirements.®问题空间并行Release的开发:如何在开发Release2.0的同时维护Release1.0出差与异地工作:源代码版本失控,或者控制手段过于复杂相似项目/产品的管理:每个项目都在低水平重复公共代码的管理:项目间彼此影响®基本原理与方法基本原理与方法基本原理与方法基本原理与方法–版本合并版本合并版本合并版本合并版本合并(Merge)两个程序员同时修改某个文件的内容,如何合并?程序员在自己的工作空间完成了若干修改,如何将这些修改提交到公共区域,而不覆盖别人的工作成果?程序员如何拿到公共区域里最新的代码,更新自己的工作空间,同时又保证自己刚刚改过的内容不丢失?在产品发布1.0版本后,同时在开发1.1修正版和2.0升级版,如何将1.1版里的缺陷修正带到2.0版里?这些话题都涉及到版本合并(merge)。版本合并(merge)是软件版本控制(versioncontrol)和软件配置管理(softwareconfigurationmanagement)的基础。抽象(2)抽象(3)抽象(4)抽象(5)解法一:分解角红色球:左下角2,左上角2,右上角3=右下角3绿色球:左下角3,左上角2,右上角2=右下角3蓝色球:左下角3,左上角3,右上角2=右下角2中在合并文件的时候,把文件分解成内容块,逐块比较和合并。在合并一个目录的时候,把目录分解成文件和子目录。(注意,这里说的目录,指的是目录的全部内容,而不是它的包含的文件和子目录的信息列表。)如果把任务单元(Task)定义为若干文件和若干目录的变更,那么当我们把一个任务单元贴到工作空间,也就是整个文件树上的时候,会分别合并任务单元中的每一个相关文件和相关目录。例子假定有个任务单元,包含目录A、文件B和目录C的变更。任务单元记录着A、B、C各自的变更前版本和变更后版本,如果它们存在的话。我们现在要把这个任务单元合并到工作空间。我们分头考虑A、B和C。考虑A:目录A的变更前版本和工作空间里的当前内容完全相同。那么,我们不需要把A再分解了,直接用A的变更后版本覆盖工作空间中的当前内容就行了。考虑B:文件B是任务单元中新创建的文件,从无到有。它在工作空间中还不存在。那么,我们也不需要把B再分解了,直接把这个新文件复制到工作空间的相对应位置就可以了。考虑C:目录C中仅有一个文件D的内容发生了变化,而文件D的变更前版本与文件D在工作空间中的当前内容有不一样。那么,我们需要认真研究文件D的这三个版本的内容,来得到一个新的合并后的版本。这就需要把文件D分解成若干内容块,逐一比较和合并。合并的类型如果左下角=左上角=右上角,那么没有冲突和改变,右下角的值应该与三角中任一角相同。如果左下角左上角=右上角,那么,右下角取左下角的值。这是一类安全的冲突。如果左下角=左上角右上角,那么,右下角取右上角的值。这是一类安全的冲突。如果左下角=右上角左上角,那么,右下角取左下角、右上角的值。发生这种情况,一般是因为有一条秘密小道,已经提前把改动带过去了。这是带给人一点惊奇的冲突。如果左下角、左上角、右上角两两互不相同。一般说来,需要进一步分解:目录分解为文件,文件分解为内容块。如果在内容块一级还是互不相同,那么这是最严重的冲突,无法通过‘自动’合并解决,需要人工干预。特殊情况。如果左下角、左上角、右上角两两互不相同,但左下角或右上角是空的,那么我们基本可以断定,右下角应该取左下角和右上角中非空的那个角的值。但是,这并不总是对的:比如,万一文件不是被删除了,而是被分拆成两个文件了呢。这是一类‘自动’合并存在风险的冲突。但不是最严重的冲突。关于冲突冲突是有类型的,比如“左下角左上角=右上角”就是其中的一种。冲突是有严重等级的。有的很轻,可以很安全的‘自动’合并。有的则很严重,没法‘自动’合并。冲突是有层次关系的,因为要合并的内容是有层次关系的。一个目录级的冲突可能包括若干文件级的冲突;一个文件级的冲突可能包括若干内容块的冲突。父冲突的严重等级等于其若干子冲突的严重等级中最高的那一个。借此,在计算机‘自动’版本合并之后,我们人类可以通过查看父冲突的严重等级,来知道是否需要继续查看其包含的子冲突的具体内容。::::分解边分解边分解边分解边拆分原则拆分原则拆分原则拆分原则变更总是有逻辑意义的,比如,修复了一个缺陷,对已有功能实现了一个小的改进,或者新添加了一个功能。总体的变更是由若干这样有逻辑意义的小变更组成的。那么我们就根据逻辑意义来拆分变更。并且。我们把每个逻辑意义的小变更叫做一个任务单元(Task)。它可能包括了对若干个文件/目录的修改。在这个任务单元里,我们既记录相关文件/目录的变更前版本,也记录变更后版本。这样,对于每个任务单元,我们就知道如何合并了。而对于任务单元的集合,也就是总体的变更,我们也就知道如何处理了。综合应用综合应用综合应用综合应用假定,你面临着如下挑战:假定你所在的团队在开发一个软件产品,该产品是由若干子产品组成的,就好像汽车是由发动机,轮子,主体框架等等组成的。在产品发布1.0版本后,同时在开发1.1版和1.0_A用户专版。所谓1.0_A用户专版,其实和1.0版差不多,换了些图标,还应客户要求添加了一个特殊功能,接收该用户另一个软件系统的输入。现在,要生成1.1_A用户专版,因为1.1版跟1.0版相比,修正了很多缺陷,还做了一些小的改进。综合应用综合应用综合应用综合应用((((2))))我们首先拆分角。把产品拆分成组件。然后我们拆分边。把每个组件在产品1.0版和1.0_A用户专版中的变化都拆分成任务单元,分头考虑,再行综合。当然,这是有前提的,那就是,当你对1.0版进行修改以产生1.0_A用户专版的时候,是按任务单元一个一个完成的。接着回到拆分角。把每个任务单元拆分成若干个文件/目录的变化。每个文件/目录有它的变更前版本和变更后版本。再拆分角。对于每个目录,如果不能一眼看出如何合并,就把它再拆分为文件和子目录。继续拆分角。对于每个文件,如果不能一眼看出如何合并,就把它再拆分为内容块。对于内容块的合并,看看它属于哪种冲突类型,然后试图‘自动’合并它。如果不能自动合并,那就留给人类来完成。®基本原理与方法基本原理与方法基本原理与方法基本原理与方法–任务单元任务单元任务单元任务单元任务单元含义任务单元含义任务单元含义任务单元含义任务单元(Task)/活动(Activity)任务单元对应一个具有整体逻辑意义的变更,比如修复了一个缺陷。另一方面,这个任务单元又对应于对多个文件/目录的具体修改,因为是这些修改实现了那个具有整体逻辑意义的变更。优点/好处记录方法记录方法记录方法记录方法记录一个任务单元,要记录每一个相关文件/目录的变更后版本,还要记录每一个相关文件/目录的变更前版本。而变更,就体现在变更前版本和变更后版本的差异。记录变更前和变更后两个版本,就以一种简单的方式,完全记录了变更。图中,上面的顶点代表某文件/目录变更前的版本,下面的顶点代表某文件/目录变更后的版本。由这两个版本,就能确定所发生的变更。而如果只用下面的顶点,不能描述所发生的变更。记录方法记录方法记录方法记录方法((((2))))要注意到变更前版本和变更后版本并不总是同时存在。当在一个任务单元中增加一个文件/目录时,该文件/目录只有变更后版本,而变更前版本不存在。当在一个任务单元中删除一个文件/目录时,该文件/目录只有变更前版本,而变更后版本不存在。当在一个任务单元中修改一个文件/目录时,该文件/目录的变更前版本和变更后版本都存在。还要注意到,不仅仅是文件可能有修改,目录也可能有修改。这里所说的目录,不是关于这个目录包含哪些文件和子目录的信息列表,而是指目录的具体内容,包括其所包含的文件和子目录的具体内容。在任务单元中,要记录相关目录的修改前版本的全部内容,和修改后版本的全部内容。这是最简单和清晰的方法。当然,在工具具体实现的时候,可以有一些优化。不论是文件,还是目录,都充当作任务单元的入口点(EntryPoint)。一个任务单元包括对若干文件/目录的变更,这是第一层。而进入每个入口点后,变更还可以进一步细分,到子目录,文件,直到文件中的内容块。任务单元的迁移任务单元的迁移任务单元的迁移任务单元的迁移—简单情况简单情况简单情况简单情况任务单元中某个文件/目录的变更前版本,与要迁移到的工作空间中的相应文件/目录的版本,其内容相同。我们只需要用任务单元中该文件/目录的变更后版本来覆盖工作空间中的相应文件/目录就可以了。任务单元的迁移任务单元的迁移任务单元的迁移任务单元的迁移—复杂情况复杂情况复杂情况复杂情况有的时候,任务单元中某个文件/目录的变更前版本,与要迁移到的工作空间中的相应文件/目录的版本,其内容并不相同。任务单元的迁移任务单元的迁移任务单元的迁移任务单元的迁移—复杂情况复杂情况复杂情况复杂情况((((2))))解决的办法是,我们对任务单元中的内容进行变形,