Java文件合并变得语义化
與任何程序員交談,并詢問他應(yīng)該如何進(jìn)行合并:“它應(yīng)該理解代碼,對(duì)其進(jìn)行解析,然后根據(jù)結(jié)構(gòu)進(jìn)行合并” –他很可能會(huì)說。
而這恰恰是SemanticMerge for Java所做的:它解析要合并的文件(加上祖先或“文件在更改之前的狀態(tài)”)并根據(jù)該信息進(jìn)行操作。
為什么所有關(guān)于合并的嗡嗡聲?
開發(fā)軟件是一個(gè)協(xié)作過程。 如果您在團(tuán)隊(duì)中工作,遲早會(huì)有兩個(gè)開發(fā)人員修改同一個(gè)文件。 每當(dāng)發(fā)生這種情況
您將不得不合并。 實(shí)際上,合并并不局限于創(chuàng)建分支(正如許多人會(huì)說的那樣),而是綁定到在相同文件上工作的開發(fā)人員,即使他們?cè)谕粋€(gè)分支上進(jìn)行合并(如果兩個(gè)人在同一個(gè)分支上,在同一個(gè)文件上工作,他們將必須在簽到時(shí)合并-或在Git行話中“提交”。
在合并方面,新一代的分布式版本控制系統(tǒng)(DVCS)比上一代做得更好。 這就是為什么許多人從SVN,CVS和較舊的替代產(chǎn)品跳到Git的原因。
下一步不僅是在如何處理文件方面的更好算法,下一步是創(chuàng)建一種更好的機(jī)制來合并“文件內(nèi)部”,這正是SemanticMerge的全部意義所在。
SemanticMerge旨在降低保持代碼干凈的成本
在開發(fā)合并工具時(shí),我們始終牢記兩個(gè)圖形:1981年的Barry Bohem的更改成本和20年后的Kent Beck的相同圖形:
一代又一代的開發(fā)人員被教導(dǎo)“波西姆原理”:“進(jìn)行生產(chǎn)變更,與分析階段引入的相同變更相比,這將花費(fèi)您一筆巨款”。
然后,貝克提出了類似的內(nèi)容:“保持代碼干凈,更改成本將保持不變”,這是敏捷方法背后的基石。
而這恰恰是SemanticMerge背后的口頭禪:保持代碼干凈。 為什么? 因?yàn)樗谢貓?bào)。
通常,您會(huì)看到需要重新布置的類:“放下這兩個(gè)私有方法,將公共構(gòu)造函數(shù)上移,將私有字段移至底部……”但是您不這樣做的原因是,也許有人觸摸該文件,合并將變得地獄。 這正是SemanticMerge所解決的問題:它“知道”您移動(dòng)了一個(gè)方法,因此不會(huì)被它所愚弄。
語義合并
現(xiàn)在讓我們研究一個(gè)典型的語義合并情況。 假設(shè)您有一個(gè)帶有幾種方法的類。 第一個(gè)開發(fā)人員將其中一個(gè)方法移動(dòng)到類中的其他位置,并且還修改了該方法。 同時(shí),第二個(gè)開發(fā)人員在原始位置修改了該方法。
查看下圖:
常規(guī)的基于文本的合并工具將無法處理這種情況,但是SemanticMerge能夠識(shí)別該方法發(fā)生了什么并提出以下合并情況:
如您所見,它標(biāo)識(shí)方法“ onBuildHeaders”已被并行修改(檢查打印方法名稱的欄兩側(cè)的“ c”圖標(biāo)),并且已移至其中一個(gè)貢獻(xiàn)者(選中“ m”圖標(biāo))。
現(xiàn)在,進(jìn)行合并的開發(fā)人員可以在“ onBuildHeaders”方法上運(yùn)行“合并”,該方法將僅合并沖突的方法,并保留新位置。
SemanticMerge如何工作?
您可能會(huì)猜到,SemanticMerge首先解析所涉及的3個(gè)文件的代碼(原始文件加上兩個(gè)貢獻(xiàn)者),然后計(jì)算每個(gè)文件的結(jié)構(gòu):它是代碼的樹狀表示。
完成此操作后,SemanticMerge開始使用3棵樹:首先,它計(jì)算出一個(gè)貢獻(xiàn)者和原始版本之間的差異,然后與另一個(gè)貢獻(xiàn)者重復(fù)該過程。
第三步是合并計(jì)算本身:它將遍歷兩對(duì)差異,并檢查它們是否碰撞。 如果它們這樣做,則存在合并沖突。 如果同一方法已被移動(dòng)或修改兩次,以此類推,則可能發(fā)生這種情況。 計(jì)算會(huì)稍微復(fù)雜一點(diǎn),因?yàn)椴粌H必須在沖突相同方法時(shí)計(jì)算沖突,而且還必須在容器中存在沖突時(shí)計(jì)算沖突(例如在父類之間進(jìn)行“有區(qū)別的”重命名等)。
還值得補(bǔ)充的是,為了在重命名方法(或字段,屬性等)時(shí)跟蹤它們,SemanticMerge計(jì)算“相似性索引”以查看方法主體之間的接近程度以及匹配度何時(shí)良好,它假定它是相同的元素。
一些數(shù)字
我們重新運(yùn)行了約4萬個(gè)合并,下載了將近500個(gè)開源項(xiàng)目。 這意味著我們提取存儲(chǔ)庫,找到所有合并,然后通過SemanticMerge工具再次運(yùn)行它們。
這樣做,我們發(fā)現(xiàn)了以下數(shù)字:
- 當(dāng)前的合并中有23%是“語義”的-這意味著它們具有的內(nèi)容不是“變-變”沖突。 它可以是代碼移動(dòng),在同一位置添加多個(gè)方法,移動(dòng)和更改方法等等。
- 在這4萬次合并中,我們發(fā)現(xiàn)1.54%的合并從手動(dòng)變?yōu)槿詣?dòng)。 這不是一個(gè)很大的數(shù)字,這意味著一旦團(tuán)隊(duì)開始使用SemanticMerge,它就會(huì)增長(zhǎng)。 (這些數(shù)字是使用與當(dāng)前語言無關(guān)的合并工具重新運(yùn)行合并的結(jié)果,因此開發(fā)人員傾向于避免對(duì)文件進(jìn)行復(fù)雜的更改)。
- 當(dāng)我們通過SemanticMerge和傳統(tǒng)的基于文本的合并工具運(yùn)行代碼時(shí),我們計(jì)算了合并沖突中涉及的行數(shù),我們發(fā)現(xiàn),使用SemanticMerge,沖突中涉及的代碼行減少了97%……這意味著工作量減少了去做!!
免費(fèi)開源
在測(cè)試SemanticMerge時(shí),我們提取了大約500個(gè)長(zhǎng)期運(yùn)行,狂熱的開放源代碼存儲(chǔ)庫,然后“重放”了所有合并。 在列表中,有諸如hibernate,openjdk,apache-lucene,jbos,monodevelop,mono,monomac,monogame,nhibernate之類的存儲(chǔ)庫,這確實(shí)很有幫助。
因此,我們決定免費(fèi)為對(duì)開源項(xiàng)目做出貢獻(xiàn)的開發(fā)人員免費(fèi)使用SemanticMerge,因?yàn)槲覀兿嘈趴梢曰仞仭?您可以在這里查看 !
翻譯自: https://www.javacodegeeks.com/2013/06/java-file-merging-goes-semantic.html
總結(jié)
以上是生活随笔為你收集整理的Java文件合并变得语义化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3个简单步骤即可测试Java 8
- 下一篇: 深圳清算中心(深圳清算备案)