与任何程序员交谈,并询问他应该如何进行合并:“它应该理解代码,对其进行解析,然后根据结构进行合并” –他很可能会说。
而这恰恰是SemanticMerge for Java所做的:它解析要合并的文件(加上祖先或“文件在更改之前的状态”)并根据该信息进行操作。
为什么所有关于合并的嗡嗡声?
开发软件是一个协作过程。 如果您在团队中工作,迟早会有两个开发人员修改同一个文件。 每当发生这种情况
您将不得不合并。 实际上,合并并不局限于创建分支(正如许多人会说的那样),而是绑定到在相同文件上工作的开发人员,即使他们在同一个分支上进行合并(如果两个人在同一个分支上,在同一个文件上工作,他们将必须在签到时合并-或在Git行话中“提交”。
在合并方面,新一代的分布式版本控制系统(DVCS)比上一代做得更好。 这就是为什么许多人从SVN,CVS和较旧的替代产品跳到Git的原因。
下一步不仅是在如何处理文件方面的更好算法,下一步是创建一种更好的机制来合并“文件内部”,这正是SemanticMerge的全部意义所在。
SemanticMerge旨在降低保持代码干净的成本
在开发合并工具时,我们始终牢记两个图形:1981年的Barry Bohem的更改成本和20年后的Kent Beck的相同图形:
一代又一代的开发人员被教导“波西姆原理”:“进行生产变更,与分析阶段引入的相同变更相比,这将花费您一笔巨款”。
然后,贝克提出了类似的内容:“保持代码干净,更改成本将保持不变”,这是敏捷方法背后的基石。
而这恰恰是SemanticMerge背后的口头禅:保持代码干净。 为什么? 因为它有回报。
通常,您会看到需要重新布置的类:“放下这两个私有方法,将公共构造函数上移,将私有字段移至底部……”但是您不这样做的原因是,也许有人触摸该文件,合并将变得地狱。 这正是SemanticMerge所解决的问题:它“知道”您移动了一个方法,因此不会被它所愚弄。
语义合并
现在让我们研究一个典型的语义合并情况。 假设您有一个带有几种方法的类。 第一个开发人员将其中一个方法移动到类中的其他位置,并且还修改了该方法。 同时,第二个开发人员在原始位置修改了该方法。
查看下图:
常规的基于文本的合并工具将无法处理这种情况,但是SemanticMerge能够识别该方法发生了什么并提出以下合并情况:
如您所见,它标识方法“ onBuildHeaders”已被并行修改(检查打印方法名称的栏两侧的“ c”图标),并且已移至其中一个贡献者(选中“ m”图标)。
现在,进行合并的开发人员可以在“ onBuildHeaders”方法上运行“合并”,该方法将仅合并冲突的方法,并保留新位置。
SemanticMerge如何工作?
您可能会猜到,SemanticMerge首先解析所涉及的3个文件的代码(原始文件加上两个贡献者),然后计算每个文件的结构:它是代码的树状表示。
完成此操作后,SemanticMerge开始使用3棵树:首先,它计算出一个贡献者和原始版本之间的差异,然后与另一个贡献者重复该过程。
第三步是合并计算本身:它将遍历两对差异,并检查它们是否碰撞。 如果它们这样做,则存在合并冲突。 如果同一方法已被移动或修改两次,以此类推,则可能发生这种情况。 计算会稍微复杂一点,因为不仅必须在冲突相同方法时计算冲突,而且还必须在容器中存在冲突时计算冲突(例如在父类之间进行“有区别的”重命名等)。
还值得补充的是,为了在重命名方法(或字段,属性等)时跟踪它们,SemanticMerge计算“相似性索引”以查看方法主体之间的接近程度以及匹配度何时良好,它假定它是相同的元素。
一些数字
我们重新运行了约4万个合并,下载了将近500个开源项目。 这意味着我们提取存储库,找到所有合并,然后通过SemanticMerge工具再次运行它们。
这样做,我们发现了以下数字:
- 当前的合并中有23%是“语义”的-这意味着它们具有的内容不是“变-变”冲突。 它可以是代码移动,在同一位置添加多个方法,移动和更改方法等等。
- 在这4万次合并中,我们发现1.54%的合并从手动变为全自动。 这不是一个很大的数字,这意味着一旦团队开始使用SemanticMerge,它就会增长。 (这些数字是使用与当前语言无关的合并工具重新运行合并的结果,因此开发人员倾向于避免对文件进行复杂的更改)。
- 当我们通过SemanticMerge和传统的基于文本的合并工具运行代码时,我们计算了合并冲突中涉及的行数,我们发现,使用SemanticMerge,冲突中涉及的代码行减少了97%……这意味着工作量减少了去做!!
免费开源
在测试SemanticMerge时,我们提取了大约500个长期运行,狂热的开放源代码存储库,然后“重放”了所有合并。 在列表中,有诸如hibernate,openjdk,apache-lucene,jbos,monodevelop,mono,monomac,monogame,nhibernate之类的存储库,这确实很有帮助。
因此,我们决定免费为对开源项目做出贡献的开发人员免费使用SemanticMerge,因为我们相信可以回馈。 您可以在这里查看 !
翻译自: https://www.javacodegeeks.com/2013/06/java-file-merging-goes-semantic.html