要理解为什么 Git 不提供您所说的某种“继承机制”(不涉及提交),您必须首先了解这些 SCM 的核心概念之一(例如 Git 与 ClearCase)
在线性系统中,配置规范可以指定几个规则来实现您看到的“继承”(对于给定的文件,首先选择某个版本,如果不存在,则选择另一个版本,如果不存在,则选择一个第三,以此类推)。
分支是线性历史中的一个分支,是给定选择规则的给定版本(在此之前的所有其他选择规则仍然适用,因此产生“继承”效果)
在 DAG 中,提交代表您将获得的所有“继承”;没有“累积”的版本选择。此图中只有一个路径可以选择您将在此确切点(提交)看到的所有文件。
分支只是此图中的一条新路径。
要在 Git 中应用其他版本,您必须:
但由于 Git 是基于 DAG 的 SCM,它总是会导致新的提交。
您在 Git 中“失去”的是某种“组合”(当您选择具有不同连续选择规则的不同版本时),但这在D VCS中是不切实际的(如在“分布式”中):当您使用 Git 创建一个分支,您需要有一个明确定义的起点和内容,并且可以轻松复制到其他存储库。
在纯粹的中央 VCS 中,您可以使用您想要的任何规则来定义您的工作区(在 ClearCase 中,您的“视图”,快照或动态)。
unknown-google在评论中添加(以及上面的问题):
所以,一旦我们看到这两种模型可以实现不同的事情(线性与 DAG),我的问题是:哪些是现实生活场景(尤其是对于 OSS 以外的公司)线性可以做 DAG 不可能的事情?他们值得吗?
当谈到选择规则方面的“现实生活场景”时,您可以在线性模型中为同一组文件设置多个选择规则。
考虑这个“配置规范”(即 ClearCase 选择规则的“配置规范”):
element /aPath/... aLabel3 -mkbranch myNewBranch
element /aPath/... aLabel2 -mkbranch myNewBranch
它选择所有标记为“ aLabel2
”的文件(并从那里分支),除了那些标记为“ aLabel3
”的文件 - 并从那里分支 - (因为该规则在提到“ aLabel2
”的那个之前)。
这值得么?
不。
实际上,出于简单的原因, ClearCase 的 UCM 风格(ClearCase 产品中包含的“统一配置管理”方法,代表从基本 ClearCase 使用中推导出的所有“最佳实践”)不允许这样做。一组文件称为“组件”,如果您想针对给定标签(称为“基线”)进行分支,则将按照以下配置规范进行翻译:
element /aPath/... .../myNewBranch
element /aPath/... aLabel3 -mkbranch myNewBranch
element /aPath/... /main/0 -mkbranch myNewBranch
您必须选择一个起点(此处为“ aLabel3
”)并从那里开始。如果您还想要“ aLabel2
”中的文件,则将所有“ ”文件合并aLabel2
到“myNewBranch”中的文件。
这是您不必使用 DAG 进行的“简化”,其中图形的每个节点代表一个分支的唯一定义的“起点”,无论所涉及的文件集是什么。
合并和变基足以将该起点与给定文件集的其他版本结合起来,以实现所需的“组合”,同时将特定历史记录隔离在分支中。
总体目标是在“应用于连贯组件的连贯版本控制操作”中进行推理。“连贯”的文件集是处于明确定义的连贯状态的文件:
- 如果已标记,则其所有文件都已标记
- 如果分支,其所有文件将从相同的唯一起点分支
这在 DAG 系统中很容易做到;在线性系统中可能会更加困难(尤其是在“配置规范”可能很棘手的情况下使用“Base ClearCase”),但它是通过同一基于线性工具的 UCM 方法强制执行的。
不是通过“私有选择规则技巧”(使用 ClearCase,一些选择规则顺序)实现“组合”,而是仅通过 VCS 操作(变基或合并)实现它,这为每个人留下了清晰的跟踪(相反到开发人员私有的配置规范,或在一些但不是所有开发人员之间共享)。再次强调,与“动态灵活性”相反,它增强了一种连贯性,您以后可能很难重现这种感觉。
这可以让你离开VCS(版本控制系统)的领域,进入SCM(软件配置管理)的领域,它主要关注的是“再现性”。而这(SCM 功能)可以通过基于线性或基于 DAG 的 VCS 来实现。