ClearCase 中的分支和流之间有什么区别?
1 回答
分支是并行化给定文件的版本历史的经典版本控制方法:请参阅“何时应该分支”
Stream不是一个分支:它只是一个元数据,能够记住任何引用 Stream 的视图将看到的基线。
创建 Stream 时,什么都不会发生(没有创建分支)。
但是在签出文件时将使用 Stream名称:任何视图都将设置其配置规范,以便创建以 Stream 命名的分支,以隔离所述分支中的开发工作。
(请参阅“如何在 ClearCase 中创建某些项目或流的快照视图? ”)
这就是充分命名 Stream 很重要的原因:如果我创建一个名为“ VonC
”的 Stream,您最终会看到(在任何修改文件的版本树中)一个名为“ VonC
”的分支:分支的目的是什么“ VonC
” ?
如果我创建了一个名为“ REL2.2_FIX
”的 Stream,您将看到名为“”的分支REL2.2_FIX
,并且会推断出任何引用该 Stream 的视图都会在 2.2 版上产生修复:这是一个更有用的名称。(这就是为什么我不喜欢“每个开发者模型一个流”的原因)
因此,如果您有任何可写组件,则可以将 Stream 视为分支的模板:
- 你在流中声明你需要什么(你想看到什么基线)
- 您在该流上创建一个视图
- 任何结帐都会创建一个以Stream命名的分支。
(这就是为什么这么多 UCM 用户将“Stream”与“branch”混为一谈的原因)
但是,如果您的项目中只有不可写的组件,那么 Stream 只是您希望在将在所述 Stream 上创建的任何视图中看到的基线列表(组件上的标签)。
这成为一种可视化机制,对于测试环境很有用,您只需访问一组组件的精确版本即可测试您的系统。
在这种情况下,不会创建任何分支,因为不会对任何文件进行检出:组件在 UCM 项目中被声明为不可写。
流和分支之间的另一个主要区别是流在层次结构中的组织(父流/子流)。
分支根本不存在该层次结构:当您有 3 个分支时A
,B
, C
:
- 完成工作后,您不知道从哪里合并分支
A
。 - 您所做的任何合并都具有相同的含义:
A->B
, orC->A
, orB->C
, or ...
使用 Stream,您将拥有:
MyProject_Int
|
--MyProject_Dev
|
-- MyProject_Feature1
Streams 的层次结构用于:
- 引入可能的合并工作流程(您知道应该从一个流合并到另一个流的位置:即其父级。这不是强制性的,但至少您有一种直观的方式知道:
Feature1
,一旦完全开发,将返回(合并到)MyProject_Dev
(其父 Stream),并且:MyProject_Dev
,一旦达到稳定状态,就可以合并到其父 StreamMyProject_Int
中,可以在其中进行集成测试,同时不间断地进行开发MyProject_Dev
。
- 为这些合并添加含义:
- 从子流合并到其父流或任何其他父流(例如,如果必须,可以直接从
MyProject_Feature1
to合并MyProject_Int
)称为 adeliver
。 - 从父 Stream (like
MyProject_Dev
) 合并到直接子 Stream (like (MyProject_Feature1
) 称为 arebase
。
其目的是确保Feature1
使用 的最新更改进行开发Dev
,以使最终交付尽可能轻松:使用常规变基,公共代码集在从这两个流派生的两个分支的两个并行历史之间不会有太大差异。
- 从子流合并到其父流或任何其他父流(例如,如果必须,可以直接从
请记住,这两个 UCM 操作本质deliver
上rebase
只是两个分支A
和B
.
但是,由于它们的名称,您知道您不只是在任何两个分支之间合并,而是在子流和父流 ( deliver
) 之间,或者在父流和子流 ( rebase
) 之间合并。