我的问题是关于 Git 处理分支的方式:每当您从提交分支时,该分支都不会收到来自父分支的更改,除非您 力量 合并它。

但在其他系统中,例如 Clearcase 或 Accurev,您可以指定如何填充分支 某种继承机制: :我的意思是,使用 Clearcase,使用 config_spec,您可以说“获取分支 /main/issue001 上修改的所有文件,然后继续处理 /main 上的文件或使用此特定基线”。

在 Accurev 中,您也有一个类似的机制,让流接收来自上层分支的更改(流如何称呼它们),而无需在分支上合并或创建新的提交。

使用 Git 的时候你不会错过这一点吗?你能列举一下这样的场景吗 遗产 是必须的?

谢谢

更新 请阅读下面的 VonC 答案,以真正集中我的问题。一旦我们同意“线性存储”和基于 DAG 的 SCM 具有不同的功能,我的问题是: 在现实生活中哪些场景(特别是对于 OSS 以外的公司),线性可以做 DAG 做不到的事情?它们值得吗?

有帮助吗?

解决方案

要理解为什么 Git 不提供某种您所说的“继承机制”(不涉及提交),您必须首先了解以下内容之一: 核心概念 这些 SCM(Git 与以 ClearCase 为例)

  • ClearCase 使用 线性版本存储: :元素(文件或目录)的每个版本都直接链接 线性 与同一元素的先前版本的关系。

  • Git 使用一个 有向无环图- 有向无环图: :文件的每个“版本”实际上是树中全局更改集的一部分,树本身也是提交的一部分。之前的版本必须在之前的提交中找到,可以通过单个有向非循环图路径访问。

在线性系统中,配置规范可以指定几个规则来实现您所看到的“继承”(对于给定文件,首先选择某个版本,如果不存在,则选择另一个版本,如果不存在,则选择一个第三,依此类推)。

该分支机构是一个 在一个 线性 历史记录给定选择规则的给定版本(该规则之前的所有其他选择规则仍然适用,因此具有“继承”效果)

在 DAG 中,一次提交代表您将获得的所有“继承”;没有“累积”版本选择。该图中只有一条路径可以选择您在此时(提交)将看到的所有文件。
分支只是该图中的一条新路径。

要在 Git 中应用某些其他版本,您必须:

  • 将一些其他提交合并到您的分支中(例如在 git pull 中提到的) st小队的回答) 或者
  • 重新调整你的分支的基础(如 格雷格提到)

但由于 Git 是基于 DAG 的 SCM,因此它总是会产生新的提交。

使用 Git “丢失”的是某种“组合”(当您使用不同的连续选择规则选择不同版本时),但这在 DVCS(如“分布式”):当你使用 Git 创建分支时,你需要有一个起点 和一个内容 定义明确并易于复制到其他存储库。

在纯粹的中央 VCS 中,您可以使用您想要的任何规则来定义您的工作区(在 ClearCase 中,您的“视图”,快照或动态)。


未知的谷歌 在评论中添加(以及在上面的问题中):

因此,一旦我们看到这两个模型可以实现不同的目标(线性与 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 来实现。

其他提示

这听起来像你要寻找的可能是 git rebase 。重订一个分支概念从原来的分支点分离,并在其他一些点重新佩戴它。 (在现实中,底垫通过施加在序列上与新的分支点的分支的每一个片,创建一组新的补丁来实现的。)在您的例子,可以变基分支到上支路的当前尖端,这将基本上“继承”至另一分支的所有更改。

我不是你的要求完全清楚,但它听起来像Git的 跟踪语义是你想要什么。当你从上午起源分支 你可以这样做:

GIT中-t -b my_branch原点/主

并且将来“混帐拉” S会自动合并origin / master的到您的 工作分支。然后,您可以使用“git的樱桃产地-v /主”看 有什么区别。在发布之前,您可以使用“git的重订”你 更改清理历史,但你不应该使用一次重订 你们的历史是公众(即其他人都在下面分支)。

至于由AccuRev的使用的继承方案:GIT用户可能“得到”整个事情时,看看混帐流(另见: http://github.com/nvie/gitflow http://jeffkreeftmeijer.com/2010/why-arent-你-使用-git的流/

此GIT分支模型或多或少确实(手动/与GIT中流动工具的帮助下)什么AccuRev的外的现成自动并用的 GUI支持确实

所以的出现的GIT能做做什么的AccuRev。因为我从来没有实际使用的git /混帐流一天到一天,我真的不能说,它是如何工作,但它看起来很有希望。 (减号正确GUI支持: - )

我会尽力回答你的问题。(这里我必须说,我没有使用过GIT,只是读过它,所以如果我下面提到的内容有错误,请纠正我)

“你能列举出必须继承的场景吗?”

我不会说这是必须的,因为您可以使用现有的工具解决问题,并且可能是适合您的环境的有效解决方案。我想这更多的是流程的问题,而不是工具本身的问题。我们的目标是确保您的流程是连贯的,并且允许您及时返回以重现任何中间步骤/状态,优点是该工具可以让您尽可能轻松地运行流程和 SCMP

我能看到的一个场景是很方便的 '遗产' 行为并使用配置规范的力量,就是当你想要你的一组更改时”孤立" 映射到任务(devtask、CR、SR 或任何定义变更集的目的/范围的内容)

使用这种组合可以让您的开发分支变得干净,并且仍然使用其余代码的不同组合(使用组合),并且仍然有 仅与任务相关的内容 期间被隔离在一个分支中 所有的 任务的生命周期,直到集成阶段。

作为纯粹主义者必须提交/合并/变基只是为了有一个“定义的起点”,我想它会'污染' 您的分支,您最终将在您的分支/更改集中得到您的更改+其他更改。

这种隔离何时/何地有用?以下几点可能仅对追求 CMM 和某些 ISO 认证的公司有意义,对于其他类型的公司或 OSS 可能没有兴趣

  • 由于非常挑剔,您可能希望准确计算与单个开发人员相对应的更改集的代码行数(添加/修改/删除),稍后用作代码和工作量估计的一个输入。

  • 将代码放在单个分支中(不与其他更改粘合在一起)可以更轻松地在不同阶段检查代码

在由多个团队和超过 500 名开发人员积极同时处理相同基本代码的大型项目中,(其中图形化的单个元素版本树看起来像一个杂乱的、纠结的网络,有多个负载线,每个大客户一个,或者每个技术一个)大型配置使用多个深度组合的规范使这么多人能够无缝地工作,使相同的产品/系统(基本代码)适应不同的目的。使用此配置规范,动态地为每个团队或子团队提供他们需要的内容和需要分支的不同视图(在几种情况下级联),无需创建中间集成分支,或不断合并和重新建立所有分支您需要开始的部分。来自同一任务/目的的代码是不同标签的分支,但有意义。(您可以在这里争论“已知基线”作为SCM的原则,但是书面SCM计划中考虑的简单标签做了这项工作)必须用Git解决这个问题(我猜是以一种非动态方式),但是我发现没有这种“继承”行为,很难想象。我猜 VonC 提到的“如果分支,它的所有文件将从相同的唯一起点分支”在这里被打破了,但除了 SCMP 上有详细记录之外,我记得这样做有很强的商业理由。

是的,构建我上面提到的这些配置规范并不是免费的,一开始有 4-5 个高薪人员在 SCM 后面,但后来通过自动脚本减少了数量,这些脚本会询问您想要什么标签/分支/功能,并将为你写CS。

这里的可重复性是通过将配置规范与任务一起保存在 devTask 系统中来实现的,因此每个任务上游映射到需求,下游映射到配置规范,一组更改(代码文件、设计文档、测试文档) ETC)

因此,直到这里的一个结论可能是一个结论,只有当您的项目大/复杂时(并且您在项目的生活中都可以负担得起SC经理的负担:))然后,您只有在需要“继承”行为或真正的多功能工具,否则您将直接转到免费的AA工具,该工具是免费的,并且已经照顾了您的SCM的连贯性...但 SCM 工具上可能还有其他因素,可能会让您坚持使用其中一个或另一个……继续阅读……

一些旁注,这可能超出了主题,但我想在某些情况下像我这样需要考虑。

我必须在这里补充一点,我们使用“good-ol CC”而不是UCM。完全同意VonC的观点 好的方法可以“引导”灵活性,实现更连贯的配置. 。好处是 CC 非常灵活,您可以找到(不费吹灰之力)一种使事物保持一致的好方法,而在其他 SCM 中您可能可以免费获得它。但例如这里(以及我使用 CC 工作过的其他地方)对于 C/C++ 项目,我们无法承担没有 C/C++ 项目的代价 温金 功能(重用 Derive 对象),可减少 X 倍的编译时间。可以说,拥有更好的设计、更加解耦的代码和优化 Makefile 可以减少编译整个东西的需要,但有些情况下,您需要每天多次编译整个野兽,并共享 DO 保存大量的时间/金钱。我现在所处的位置,我们尝试尽可能多地使用免费工具,并且我认为,如果我们能找到一种更便宜或免费的工具来实现 温金 特征。

我将以保罗提到的一些事情结束, 对于不同的目的,不同的工具比其他工具更好 但我要补充说,您可以通过连贯的过程来摆脱工具的一定局限 值得的? 取决于您的“问题”、您正在运行的 SDLC、您的 SCM 流程,以及是否有任何可能在您的环境中有用的额外功能(如 winkin)。

我的 2 美分

理论不谈,这里有一种对这个明显的实际拿的,从商业生产环境中使用的AccuRev了数年,我的观点:继承模型工作得非常好,只要孩子流没有分歧的太多祖先仍处于发展。当继承流过不同它分解。

继承(更高版本作为早期的儿童)允许祖先改变流是活跃在孩子没有任何人做任何事流(除非需要合并,在这种情况下,它显示为深重叠,这是件好事能够看到)。

听起来不错,而在实践中,当涉及到的所有流都相对类似。我们使用模型低于给定产品发布的修补程序和服务包级别流。 (这是比这更复杂的一个实际一点对我们来说,却是一般的想法。)

生产的排放是在平行的,不继承,与那些修复程序和服务包以下儿童每个。开始一个新的发行意味着创建一个新的版本级流,并从最近的维修流人工推动家居与之前版本进去。在此之后,适用于后来的变化早期版本必须手动推入它们各自的,需要更多的工作,但是允许更大的控制。

我们最初使用在所有版本中,当后来者是早期的儿童的继承模型。这工作得很好了一会儿,但有一段时间无法管理。跨版本的主要结构上的差异作了不可避免地继承改变一个坏主意。是的,你可以把一个快照,以阻止继承之间,但随后所有的修改都被手动推和父快照,儿童和平行的非继承流之间的唯一真正的区别是,整个图形流视图不断推下和向右,这是一个PITA。

有关AccuRev的一个非常好的事情是,你有这样的选择,所有的时间。这不是你的单片机程序的体系结构的内在约束。

你有没有注意到,你可以检出specfific文件版本的GIT吗?

只要使用这样的:

git checkout [< tree-ish >] [--] < paths >

每一样配置规范文件的任何现有版本(路径)可以被加载到worktree。从GIT中结账文档引用:

以下序列检出主分支,恢复Makefile以两个修订背部,误删除hello.c,并从索引获取回:

$ git checkout master             
$ git checkout master~2 Makefile             
$ rm -f hello.c            
$ git checkout hello.c            

ClearCase中,没有MultiSite的,是一个存储库,但GIT中是分布式的。 ClearCase的承诺在文件级别,但Git修订在仓库的水平。 (这最后的差异意味着原来的问题是基于一种误解,如在其他职位指出此处。)

如果这些都是我们正在谈论的差异那么我认为“线性”对应的是“DAG”是区分这些SCM系统一个混乱的方式。在ClearCase的一个文件中的所有版本都被称为文件的版本“树”但实际上它是一个向无环图!到Git的真正区别是,每个文件中存在的ClearCase的DAG的。因此,我认为它是误导性的指ClearCase的非DAG和GIT中为DAG。

(BTW的ClearCase版本的目录,以类似的方式,以它的文件 - 但这是另一回事)

我不知道你在问什么,但你证明的AccuRev流是不同的工具比的Git(或者SVN)的分支。 (我不知道的Clearcase。)

例如,与AccuRev的你的强制的,正如你所说,使用一定的工作流程,让您未在Git的支持变化的审计历史。 AccuRev的的继承使某些工作流更高效的和其他不可能的。

使用Git的,你可以有试探性的编码隔离在本地回购或功能分支,它不会被AccuRev的支持非常好。

不同的工具有利于不同的目的;要问什么每个人都是好是非常有用的的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top