Accurev是如何工作的一个简短解释是什么?

31
我了解git、Subversion、CVS以及其他许多源代码控制系统。我开始使用Accurev,但它令我感到困惑。我认为我需要形成一个心理模型来将其与其他SCM联系起来。最好是相对于git,因为我最了解git。 我会将git解释为“提交的有向图,其中提交是差异,父哈希和自身哈希”。你可以轻松地从那里进一步解释诸如rebase的概念以及合并的真正含义,快进与实际合并等等。我已经发现,在约15-20分钟内教新用户复杂的git概念非常容易。我真的很想以那个水平了解Accurev。所以...Accurev如何工作的一句话抽象描述是什么,这使得解释它的行为成为可能?一些我想知道的心理模型问题的例子:
  • 当我“keep”一些文件然后“promote”它们时会发生什么?
  • 如果我没有推广刚才保留的相同文件怎么办?
  • 为什么在发生非冲突(也称为重叠)更新时,历史记录有时会被错误归属?这特别类似于Subversion的一种故障模式,根据我听到的基本解释,我不认为Accurev应该存在这种情况。
  • 为什么差异几乎永远不包含我期望的内容?我相信发生的事情是针对基础的差异显示我针对当前(移动)父流的差异,但我真正想要的是只看到我上次更新以来做出的更改。

想象一下这样的情况:你有一个开发团队正在项目上工作。你还有其他团队在使用你们的项目进行他们的工作。你的公司有一个基于所有项目组合的产品(或网站)。Accurev使得在这个复杂的工作环境中管理变更流程变得容易,而不需要强制团队总是保持代码同步发布。 - Michael Shaw
18
我的一个词解释是:“糟糕”。 - nonsensickle
如果你已经厌倦了Accurev并想要离开,可以查看https://github.com/orao/ac2git将你的历史记录转换为git。 - parsley72
ac2git已经迁移,更新后的链接为https://github.com/NavicoOS/ac2git。 - nonsensickle
5个回答

26

免责声明:我最了解的源代码控制系统是SVN,因此我使用的术语,比如repo、checkout等可能有所偏见。此外,虽然我每天都在使用Accurev,但我很少涉足那些我感觉已经牢固掌握核心概念以外的领域。

一句话描述(带星号):Accurev是一个按时间顺序排列的仓库,为每个流/工作区的更改文件保留版本历史记录,并允许您在流中开发不同的代码版本,同时每个流都会从其父流和子*流透明地更新核心代码。

(*)只有当子流将更改推到父流时,父流才会被子流更新。

Accurev的主要优点在于轻松维护不同版本的代码。如果想理解它,不要寻找你熟悉的快速抽象或重新定义的术语。我建议查看示例并在需要时温和地解释术语。不幸的是,我只知道我需要知道的内容,但我会尝试…

(稍后再谈工作区。现在不必担心它们。)

当您创建一个从另一个流的父流创建的子流时,就像您执行了SVN分支操作来创建子流,但美妙的区别是,每次更新父流或子流时,SVN合并都会为您处理(或者在冲突存在且需要手动解决冲突时,提醒您)。

假设您开始有一个流,CompanyStream。您的代码库由该流管理,并且它具有您对文件所做更改的历史记录。然后,您决定在其中创建两个子流ChildStream1和ChildStream2。在CompanyStream中对文件进行的任何更改都将传播到两个子流中,因此它们始终具有从CompanyStream继承的最新代码。(版本更改的继承是Accurev中的一个基本概念。)同时,您正在ChildStream1中进行特定于一种供应商的开发,并在ChildStream2中进行特定于另一个供应商的更改。您可以有选择地决定从ChildStream1和2中哪些代码被提升到CompanyStream,但是在CompanyStream中进行的任何更改都应该是想要出现在两个子流中的内容。如果将代码从ChildStream1提升到CompanyStream,则这些更改会在ChildStream2中出现一次更新(因为它再次继承了CompanyStream)。
流的可视化如下所示: CompanyStream - |-- ChildStream1 |-- ChildStream2
Accurev重叠=在您更新流以来,父流中的文件已经被修改。将父流视为在您之上(在客户端中显示),并且该流已水平推进,以使其与您所处的时间点重叠。
SVN到Accurev概念的快速映射: SVN Checkin-Promote SVN Checkout-Anchor(将某物锚定使其成为WIP-工作中) SVN Update-Update Accurev工作区

我还没有提到工作区。 工作区表示您硬盘上的代码。 工作区类似于流,因为它可以具有历史记录,并且可以跟踪您所做的更改。 (这就是 Keep 所做的--它在您的工作区历史记录中存储在 Keep 操作期间指定的文件的快照。 您随时可以恢复到那些文件快照。 因此,一个工作区也可以被视为您自己的个人私有流,记录了对代码所做的更改。)

流是表示修订更改以及发生的事件历史记录的抽象概念。 流和工作区从其父流继承代码。 但是,与流不同,工作区不能具有子流或子工作区。 工作区就像树上的叶子; 流就像树枝。

  • 当我“保留”一些文件然后“推广”它们时会发生什么?

您将其推广到流。 您在工作区中进行 Keep 操作。 推广的更改对所有可以看到该流的人都可见。 保留的更改仅对您(工作区的所有者)可见。

保留的文件将在您的工作区中具有快照(以防您以后想要恢复它们)。 推广的文件将在您将它们推广到的流中具有快照(可以这样说)。 最大的区别在于,推广的更改将向继承该流的任何流或工作区传播。

  • 如果我没有推广与我刚刚保存的相同的文件会发生什么?

那么它们将只存在于您的工作区中。 此外,我认为当您进行推广时,Accurev 会首先进行保留操作(因此您的工作区和您要推广到的流都记录了文件更改)。

  • 为什么在非冲突(也称为重叠)更新发生时历史记录有时会被错误归因? 特别是这种情况会让人联想到 Subversion 的一个故障模式,根据我听到的基本解释,我不认为这种情况应该存在于 Accurev 中。

你能举个例子吗?我对Accurev的文件版本控制不是很清楚。我认为版本属性将由最近进行更改(而不是保留)的工作区或流分配。 可能存在一些流继承关系,导致文件具有看起来不正确的属性,直到你把它追溯出来。

  • 为什么差异几乎从未包含我期望的内容?我相信所发生的是基于基础的差异正在显示与当前(移动的)父流的差异,但我真正想要的是只看到自上次更新以来我所做的更改。

然后针对“已备份”执行差异操作,而不是针对基础执行差异操作。

对我有效的简单配置是:我总是在一些公共开发流之外创建自己的个人私有流。然后,当我想要签入(或能够还原到)的更改时,我将其提升到自己的流中。我继续在我的工作区中工作,如果我想要将我的工作区与以前所做的内容或正在进行的更改进行比较,则会针对Backed执行差异操作。

抱歉这段话这么长。希望能有所帮助...


我也不确定diff与backed的区别是否符合我的期望,但是我会为这个奇怪的diff问题创建一个不同的问题。同时,这是迄今为止最好的答案。已采纳! - Otto
我相信我理解如何提出问题。我不相信我可以对历史记录进行差异比较。我可以针对我的工作区流进行差异比较,但由于继承树是流动的,我没有上下文知道其他人进行更改时“backing”是什么,因此我无法再进行差异比较。现在将其写成一个单独的问题。 - Otto
2
“保留的更改只对您可见,即工作区的所有者。” 这并不完全正确。Accurev允许用户查看其他用户的工作区。只是这不是一个非常突出的功能;您必须去寻找它。 - Stephen

7
由于其他人已经试图回答您的直接问题,而Dave的答案最为简洁和准确,我将尝试回答您的问题:
- “保留”某些文件然后“推广”它们会发生什么?
保留文件将创建该文件的新版本,仍然私有于您的工作区。这对于自治编码、创建分流点、纯粹的私人开发非常有用。您可以随时恢复到任何以前保存的文件版本,无论是您自己还是其他贡献者的版本。当您对当前版本感到满意(已编译、构建、测试等)时,您可以将其推广到父流中,从而向其他人展示您的版本,而不会像在提交检查时间时那样破坏事物。
- 如果我没有推广与我刚刚保留的相同的文件会怎样?
再次,完全的工作区自治。如果你是那种可以跟踪自己正在做什么的开发者,你可以同时处理100个文件。您可以不推广、全部推广、一个推广或一些推广——并且您可以按照自己的时间表执行此操作。
- 为什么当非冲突(也称重叠)更新发生时,历史记录有时会被错误地归属?特别是这让我想起了Subversion的一个故障模式,从我听到的基本解释来看,我不认为在Accurev中应该存在这种情况。
我不确定您具体指的是什么。当您在AccuRev工作区中运行更新时,它永远不会覆盖您正在进行的工作。如果您正在处理将被继承的元素(意味着父级结构中的内容已更改),则它们将在您的工作区中列为(重叠)。同样,您可以选择何时执行合并,并仍然更新其他来自上方的更改,甚至可以继续处理冲突的文件。合并发生在工作区而不是在推广时,使您有机会再次编译、构建、测试结果,然后交付到其他地方。
- 为什么差异几乎从不包含我期望的内容?我相信发生的事情是基于基础的差异显示了我对当前(移动)父流的差异,但我真正想要的只是看到我自上次更新以来所做的更改。
基础差异将向您显示您的工作区版本与您最后继承自更新或工作区创建的版本之间的差异。基于备份的差异将向您显示您的版本与目前在父流中的内容之间的差异。因此,如果有人在您仍在进行的情况下推广了对该文件的更改,则基于基础的差异仅与您的原始版本进行比较,而基于备份的差异则与父级中的新内容进行比较。顺便说一句,在历史记录->浏览版本视图中,您可以将任何两个文件版本相互比较。
希望这提供了一些关于您具体问题的视角。

你已经接近让我理解了,但是我现在看到一些东西,让我觉得还缺一块拼图。比如说,如果我添加了一堆文件然后推广这些相同的文件,最终会产生两个事务。所有文件的两个事务编号都是相同的。推广事务被显示为“别名”事务。这意味着如果它们是相同的文件集,则会有一些特殊机制启动。如果没有这种机制,那么当我同时保留它们时,我总是会推广我不想推广的文件。 - Otto
我认为我真正想要的是交易视图,因为我经常遇到想要查看更改的问题。例如,代码审查,我想看看您在工作区所做的更改,而不是当前与移动备份或基础流的差异。我可能关心这些差异,但当我试图弄清楚您特定的代码更改是否正确且与您的错误/其他内容相关时,我并不关心它们。 - Otto
关于第三点,我认为你忽略了我的意思,即这是一种非重叠(我理解为冲突)的更改。如果我们的更改不重叠,就不应该涉及合并。但出于某种原因,我们总是发现代码归属错误。如果这是冲突解决,我可以理解。 - Otto

3
我会将git解释为“提交的有向图,其中提交是差异、父哈希和自身哈希。”Git存储库是历史树的森林,其中提交叶子是目录和文件的树(提交元数据加上)。至于AccuRev,我看了他们的2分钟介绍视频,它看起来与您平均按时间排列的SCM历史树(分支)差不多。具有水波图标的项是分支头,黄色文件夹类似的东西是工作副本。当演示者移动工作副本时,他似乎在重新生成所有下级的工作副本(邪恶!想想合并冲突!)。三个绿点的图标(问题列表)将是一个提交列表,然后在复制时进行挑选。简而言之:除了通过以前对cvs/svn/git的经验所知道的内容外,没有什么需要了解的。

我不必考虑合并冲突,我每天都能看到它们。但我希望我能够继续前进...这是在我加入之前做出的历史技术决策,现在我们就处于这种情况。 :) - Otto
虽然我觉得这个答案并没有让我完全理解Accurev,但我相信它总结了我目前对Accurev的理解。再加上我越来越认为没有人能够充分理解Accurev以便以合理的方式回答我的问题,所以在更好的答案出现之前,这个答案是被接受的。 - Otto

3
Accurev是从ClearCase派生而来,借鉴了ClearCase UCM流的一些特点。(Accurev模型与UCM有些相似,并且受到前ClearCase用户的好评)
Stream是一个配置,即您需要工作(编译、测试、调试等)的标签列表(只读组件)或文件(可写组件)。
这就是为什么Accurev被称为面向SCM的基于流的架构。
如果每个开发者都有一个私有流(工作区流),可以将其推广到更常见的流中。每次升级都会更新父级流的配置(这只是您需要的工作列表)。

我差点接受了这个答案。可能是因为我对Accurev的理解模型还不够,无法完全领会这个答案。 - Otto

1

根据您的问题风格,我会给您提供一个技术性(非商业性)的单句话:

AccuRev采用面向对象的方法来建模软件配置。这很简单,也很棒!特别是如果您正在建模工作流程,或者更好的是,设置持续交付(另一个话题)。但我见过太多人因为无法超越传统的“分支”(如cvs、svn、p4、cc等)而忽视了这种强大的技术和数据模型方法。最好的比喻是将一系列AccuRev流与clearcase中的配置规则进行比较...(注意:这只是一个比喻),但流比规则更强大,因为它们是维护基于时间的配置和历史记录的一级实体。

理解AccuRev的诀窍在于,虽然任何给定的“流”代表一个完整的配置(即您可以检出它),但该流的实际内容是通过聚合任何本地文件/目录更改、来自父级的任何更改以及一直向上到顶部收集其他文件的树来动态确定的。因此,每当您看到一组“流”的“树”时,它们不是分支...而是基于继承的一系列配置,其中顶级流就像“超类”,所有[子]子类都是[子]子类。新的文件/目录更改随着从开发、集成、QA等方面的推进而向上提升。希望对你有所帮助_dave

1
很抱歉,我没有任何ClearCase的上下文。这是多个句子。 - Otto
2
AccuRev采用面向对象的方法来建模软件配置。 :) - user129236
2
“面向对象”可以对任何事物进行建模,但如果没有关于模型行为的信息,则毫无意义。虽然您已经提供了部分信息,但它仍然不能回答我的问题,因为它需要对ClearCase有基本的理解,而我并没有这种理解。 - Otto
同样地,我正在寻找比“面向对象”更低层次的信息。例如,你可以将C++描述为“面向对象”,但在编译后,它实际上与C代码没有什么区别。我正在寻找有关如何组装C++二进制文件的等效详细信息。例如,“C++将类名+方法名哈希在一起,以生成最终对象二进制文件中的方法”。 - Otto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接