Java文件合并变得语义化

与任何程序员交谈,并询问他应该如何进行合并:“它应该理解代码,对其进行解析,然后根据结构进行合并” –他很可能会说。

而这恰恰是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,因为我们相信可以回馈。 您可以在这里查看 !

参考: SemanticMerge博客上的JCG合作伙伴 Pablo Santos的Java文件合并变得语义化

翻译自: https://www.javacodegeeks.com/2013/06/java-file-merging-goes-semantic.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/368202.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

KnockoutJS-快速入门

虽然在WPF中接触过MVVM模式,可是刚开始在Web中接触到Knockout.JS让我大吃一惊,简化了好多工作量,原来可能需要一大堆的JS脚本完成的工作量,被释放许多。接触KnockoutJS一年多了,在好多个项目中也用到过,虽然…

如何在一个页面添加多个不同的kindeditor编辑器

kindeditor官方下载地址:http://kindeditor.net/down.php (入门必看)kindeditor官方文档:http://kindeditor.net/doc.php (入门必看)Kindeditor编辑器初始化参数文档:http://kindeditor.net/doc…

JSONArray.fromObject不执行且不报错问题的解决

今天在写javaweb工程的时候需要向前台传json格式的数据,用到了json-lib-2.4-jdk15.jar等一系列包,然而却出现如下状况: CityBean是一个javaBean,我们看到,控制台只打印出了list的内容,而下面的两个却没能打…

爬虫-scrapy

阅读目录 一 介绍二 安装三 命令行工具四 项目结构以及爬虫应用简介 五 Spiders六 Selectors七 Items八 Item Pipeline九 Dowloader Middeware十 Spider Middleware十一 settings.py十二 爬取亚马逊商品信息一 介绍 Scrapy一个开源和协作的框架,其最初是为了页面抓取…

Java垃圾回收(4)

G1:垃圾优先 G1收集器是热点JVM中要实现的最新收集器。 自Java 7 Update 4以来,它一直是受支持的收集器。OracleGC团队也公开表示,他们对低暂停GC的希望是完全实现的G1。 这篇文章来自我之前的垃圾收集博客文章: 热点GC概述 。 …

Html5 冒泡排序演示

本文通过一个简单的小例子,简述冒泡算法在B/S中的简单使用,仅供学习分享使用,如有不足之处,还请指正。 概述 冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。 它重复地走访…

一种编写测试的好方法

测试。 最近我一直在考虑进行测试。 作为我对各种项目所做的代码审查的一部分,我已经看到了数千行未经测试的代码。 这不仅是测试覆盖率统计数据指出这一点的情况,还更多是该项目中根本没有任何测试的情况 。 我一直听到这种悲惨状况的两个原因&#xff…

rem、px、em之间的区别以及网页响应式设计写法

个人收藏用,转载自:http://www.w3cplus.com/css3/define-font-size-with-css3-rem 在Web中使用什么单位来定义页面的字体大小,至今天为止都还在激烈的争论着,有人说PX做为单位好,有人说EM优点多,还有人在说…

游戏服务器架构图

1:ARPG类型游戏 2:MMORPG 3:MOBA 4:卡牌类 5:棋盘类 转载于:https://www.cnblogs.com/like-minded/p/8297718.html

GlassFish 4带来了Java EE 7

真是惊喜 除了推出新的iOS 7外,苹果在wwdc上什么也没提供。 碰巧的是,在他们的主题演讲后不久,又有7个人正式露面。 GlassFish 4.0已于昨天晚上发布(显然是不需要的)。 新的Java EE 7参考实现自动成为当今第一个可用的…

bootstrap的栅格布局与两列布局结合使用

在工作中我们常常需要实现响应式布局,这个可以使用bootstrap的栅格系统来实现,我们在列里也需要实现一部分的响应式。比如下面的效果图,需要实现左边图标固定,右边的自适应 : 左边固定宽度,右边自适应&…

JVM性能魔术技巧

HotSpot是我们众所周知和喜爱的JVM,是Java和Scala汁流淌的大脑。 多年来,许多工程师对其进行了改进和调整,并且在每次迭代中,其代码执行的速度和效率都接近本机编译代码。 JIT(“即时”)编译器是其核心。…

mysql 10个日期,MySQL自学篇(10)——日期函数

MySQL自学篇(十)——日期函数日期和时间函数(1)获取当前日期的函数和时间的函数CURDATE()和CURRENT_DATE()函数,获取当前日期select current_date(),curdate(),curdate()0;curdate()0 表示将当前时间转化为数值型CURTIME()和CURRENT_TIME()获取当前时间select cur…

python-flask-请求源码流程

启动先执行manage.py 中的 app.run() class Flask(_PackageBoundObject):   def run(self, hostNone, portNone, debugNone, **options):from werkzeug.serving import run_simpletry:#run_simple 是werkzeug 提供的方法,会执行第三个参数 self()run_simple(ho…

正则表达式强化,爬虫练习

re模块下的常用方法 import re ret re.findall(\d(\.\d)?, 1.232.34)   print(ret) 结果: [.23,.34] # findall的正则表达式里面有分组(),()里面的内容优先显示 ret re.findall(\d(?:\.\d)?, 1.232.34)print(ret)    结果:…

Linux LVM管理

LVM(Logical Volume Manager)逻辑卷管理是在Linux2.4内核以上实现的磁盘管理技术。它是Linux环境下对磁盘分区进行管理的一种机制。 本文内容: 创建和管理LVM扩容LVM分区一、创建和管理LVM 要创建一个LVM系统,一般需要经过以下步骤: 1、 创建…

USB OTG插入检测识别

一 USB引脚一般四根线,定义如下: 为支持OTG功能,mini/micro usb接口扩展了一个ID引脚(第4脚) A设备端ID脚接地,则初始状态为Host,例如PC和支持OTG设备做主设备时 B设备端ID脚悬空,默…

CSS3与页面布局学习笔记(三)——BFC、定位、浮动、7种垂直居中方法

一、BFC与IFC 1.1、BFC与IFC概要 BFC(Block Formatting Context)即“块级格式化上下文”, IFC(Inline Formatting Context)即行内格式化上下文。常规流(也称标准流、普通流)是一个文档在被显示…

Java垃圾回收(2)

并行清理 今天,我们介绍了并行GC的工作原理。 具体来说,这是在Eden上运行Parallel Scavenge收集器,在Tenured一代中运行Parallel Mark and Sweep收集器的组合。 您可以通过传递-XX: UseParallelOldGC来获得此选项,尽管…

Navicat Premium创建MySQL存储过程

1、使用Navicat Premium打开创建函数向导,操作:连接名——数据库——函数——新建函数 2、选择过程——输入存储过程参数——完成(这一步可以不填写参数,编写存储过程代码的时候设置参数) 3、按照要求完成存储过程代码…