Codice 为他们的代码感知型合并工具增加了对 Java 语言的支持

  • Charles Humble
  • 武鑫

2013 年 6 月 17 日

话题:Java语言 & 开发

Codice 软件,也就是Plastic SCM的制作者,已经为他们的代码感知型三方代码合并【译注 1】工具 SemanticMerge 的 Beta 测试版本增加了对 Java 语言的支持,该工具由 InfoQ 在进行过报道

该工具既可用于代码合并,也可用于代码比较。该工具在结构层面上处理代码合并,而不是以“解析代码,创建中间结果树,然后将这些中间结果树作为代码比较的基础”的方式在文本块层面进行代码合并。这种方法最显著的优点是代码比较过程不会被类文件的结构性变化所困扰——例如改变方法的顺序。此外该工具还达到了“代码感知”的程度,因此,打个比方如果一个开发人员在第一行增加了一个对 java.sql.ResultSet 的 import 语句(或是一个.NET 中的 using 语句),而另一个开发人员在第 10 行增加了同样的 import 语句,SemanticMerge 会知道它们是相同的 import 语句,所以在合并时对该行只会增加一次。

有一些产品为其它开发语言提供同样的代码合并能力(Altova 的DiffDog对 XML 执行类似的工作,还有 Java 开发的 DaisyDiff库可以下至代码层面比较 HTML 文档),但是 Codice 软件的首席软件工程师 Pablo Santos Luaces 告诉我们:“我们没有真正找到任何一个完美的产品能够像 SemanticMerge 所做的那样去处理源代码,确实曾有一些工具试图达到同样的目标,但在我看来,他们要么尚未完成,要么就是试图去处理过于复杂的情况”。

与 Plastic SCM 所预期支持的一样,该工具同样可被配置为与 Git、Subversion、Perforce、ClearCase、Team Foundation Server、Mercurial 和 IntelliJ 协同工作。

目前 SemanticMerge 只有 Windows 版本,并且依赖于.NET Framework 4.0。Codice 确实已经有计划将该工具移植到 OS X 和 Linux 平台上,在该计划中,在 MacOS X 平台上将使用Xamarin Studio,而在 Linux 平台上将使用Gtk#。这两种用户界面都将是原生的,但都会运行在 C#/Mono 虚拟机上。

InfoQ 采访了 Pablo Santos Luaces 以寻求更多信息。

InfoQ:在支持 C# 和 VB.NET 之后,你们很快地增加了对 Java 语言的支持。那对于其它那些你们计划支持的语言(C,C++,Objective-C,JavaScript)而言,有没有可能也会如此迅速地推出呢?或者说这些语言做起来会更难?

我们对 Java 语言支持的开发几乎是和对 C# 及 VB.NET 语言支持的开发同步展开的,这就是为什么我们只用了一个月时间就可以发布它了。如今我们将专注于 C 和 C++。对这两种语言支持的开发工作都已开始,但是我们预计 C++ 会更难一些。我们正在使用libclang解析代码,该工具极大地简化了工作,但是我们将会需要改动合并引擎的某些部分去处理一些 C++ 独有的特性,因为这些特性在我们目前支持的语言中并不存在。我们同样也希望尽快把重点放在 JS 上,因为这是顶级需求中的一项。

InfoQ你们是使用什么算法来进行代码比较的?

代码比较和代码合并算法都是我们在 SemanticMerge 开发工作中的核心。它们都是基于“代码结构”进行处理的,而不是像 Xdiff 或是 Xmerge 等算法那样是基于文本块的。因此,该工具首先会解析代码,然后计算出基础版本和某一个贡献者版本之间的“语义差异”,接下来再计算出基础版本和另一个贡献者版本之间的“语义差异”。这两个语义差异的集合都将被用于代码合并的运算。

差异比较算法真正有趣的部分是它能够跟踪被移动了的方法。因此,假设一个方法改变了位置,也依然能够将它作为一个差异进行跟踪(这将是合并运算的基础)。“解析”停留在方法体层面,以便将方法的方法体部分作为纯文本进行处理。为了在即使方法已被修改的情况下也能够检查是否“方法仍然相同”,我们以经过大量修改的 Levenshtein 距离算法【译注 2】为基础,运行我们曾使用过的 Xdiff 算法来进行判断。如果方法体是“足够相似”的并且其余的方法元素是匹配的(比如方法参数等等),那么它就是一个相同的方法。

代码合并将使用两个差异集合来进行合并运算。如果一个方法在两个集合中都被修改了,那么你就面临代码冲突问题。而且这也适用于移动 / 移动(产生歧义的移动也会是代码冲突,例如他们被转移到不同的类文件),更改 / 删除,移动 / 删除及很多其他情况。

InfoQ:你们准备何时离开 Beta 测试阶段?

对于 C# 的支持而言,我们预期可以很快离开 Beta 测试阶段。Java 语言的支持才刚刚启动,因此将仍需在 Beta 测试阶段继续等待。我们会尽力在七月前将 C# 的版本准备好以供开始商业应用。话虽如此,我们在许多领域还有工作要做。

首先,我们需要提高工具的启动时间。目前这个工具需要几秒钟的启动时间,当你需要合并几百个文件时,这将会是一个问题,而在真实的生产情景中你难免会遇到这种情况。我们已经使用它好几个月了,这几个月用下来我们发现这个问题必须得到解决。

我们还需要添加一个“自动解决模式”,因为目前我们要求用户复查所有的代码合并,就算在 SemanticMerge 已经完全自动化地进行了代码合并的情况下也是如此。我们是故意这么做的,因为目前仍处于 Beta 测试阶段,但是我们的确需要尽快添加 --auto 选项。

我们刚刚在这个版本中增加了一个更好的文本编辑器,这是用户提出的众多需求之一。

而且你也知道,我们必须保持专注因为我们期望能够完成 Mac 版本,并尽快开始 Linux 版本的工作... 还有堆积成山的事情要做。

该工具的价格尚未设定,但是 Pablo 告诉我们,他希望通过每月 3 美元左右的包月套餐,或者 60 每月左右的无限使用计划来保持该工具是低价的。您可以在这里免费下载 Beta 测试版。

【译注 1】三方代码合并工具,是指在进行代码合并时,不仅比较需要合并的两个文件,而且会将这两个文件与基础版本进行比较,一共有三个文件一起进行比较以决定如何进行合并,故称为三方代码合并。详见:http://en.wikipedia.org/wiki/3-way_merge#Three-way_merge

【译注 2】Levenshtein 距离算法,一种字符串相似度算法。详见:

http://en.wikipedia.org/wiki/Levenshtein_distance

查看英文原文:Codice Add Java Support to their Code-Aware Merging Tool


感谢赵震一对本文的审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

Java语言 & 开发