MergeBERT: Program Merge Conflict Resolution via Neural Transformers

1 INTRODUCTION . Collaborative software development relies on version control systems such as git to track changes across files . In most projects , developers work primarily in a branch of a software repository , periodically synchronizing their code changes with the main branch via pull requests ( Gousios et al. , 2016 ) . When multiple developers make concurrent changes to the same line of code , a merge conflict may occur . According to an empirical study of four large software projects by Zimmermann ( 2007 ) up to 46 % of all merge commits result in conflicts . Resolving merge conflicts is a time-consuming , complicated , and error-prone activity that requires understanding both the syntax and program semantics , often taking more time than developing a code feature itself ( Bird & Zimmermann , 2012 ) . Modern version control systems such as git utilize the diff3 algorithm for performing unstructured line-based three-way merge of input files ( Smith , 1998 ) . This algorithm aligns the two-way diffs of two versions of the code A and B over the common base O into a sequence of diff “ slots ” . At each slot , a change from eitherA or B is selected . If both program versions introduce a change at the same slot , a merge conflict is produced , and manual resolution of the conflicting modifications is required . A versatile , production-level merge conflict resolution system should be aware of programming language syntax and semantics yet be sufficiently flexible to work with any source code files , irrespective of the programming language . It should generalize to a wide variety of real-world merge conflicts beyond a specific merge type or a domain of software artifacts . Inspired by the exceptional performance of transformer models and self-supervised pretraining in natural language understanding and generation tasks ( Devlin et al. , 2019 ; Radford et al. , 2019 ; Liu et al. , 2019 ; Lewis et al. , 2019 ; Raffel et al. , 2020 ) as well as in the programming language domain ( Feng et al. , 2020 ; Svyatkovskiy et al. , 2020 ; Clement et al. , 2020 ; Tufano et al. , 2020 ; Ahmad et al. , 2021 ) , we introduce MergeBERT : a neural program merge framework based on token-level three-way differencing and transfer learning . We select a bidirectional transformer encoder ( BERT ) as our encoder implementation . As a bidirectional encoder , BERT allows to attend to code context surrounding the conflicting chunks , which is a key advantage over left-to-right language models . To endow our model with a basic knowledge of programming language syntax and semantics , we adopt a two-step training procedure : ( 1 ) unsupervised masked language model pretraining on a massively multilingual source code corpus , ( 2 ) supervised finetuning for the sequence classification task . We transfer weights of the pretrained encoder into a multi-input model architecture that encodes all inputs that a standard diff3 algorithm takes ( two two-way diffs of input programs ) as well as the edit sequence information , then aggregate them for learning . While MergeBERT utilizes BERT , other encoder architectures such as LSTM ( Hochreiter & Schmidhuber , 1997 ) , or efficient transformer variants like Poolingformer ( Zhang et al. , 2021 ) could also be utilized for this task . The paper contributions are as follows : ( 1 ) we introduce MergeBERT a novel transformer-based program merge framework that leverages token-level three-way differencing and formulates the task of generating the resolution sequence as a classification task over a set of primitive merge patterns extracted from real-world merge commit data , ( 2 ) we effectively transfer knowledge about program syntax and types of source code identifiers from millions of software programs to downstream sequence classification task of merge conflict resolution by using self-supervised pretraining ( see section 5 ) , which also makes this approach computationally more feasible , ( 3 ) we overcome several limitations of the existing neural program merge models Dinella et al . ( 2021 ) and semi-structured program merge tools like jsFSTMerge and JDime to improve upon the state-of-the-art by 2–3× ( see sections 7 and 8 ) , and finally , ( 4 ) we demonstrate that multilingual MergeBERT is sufficiently versatile to work with programs in Java , JavaScript , TypeScript , and C # , and can generalize to unseen languages without retraining . 1.1 RELATED WORK . There have been multiple attempts to improve merge algorithms by restricting the them to a particular programming language or a specific type of applications ( Mens , 2002 ) . Typically , such attempts result in algorithms that do not scale well or have a low coverage . Syntactic merge algorithms improve upon diff3 by verifying the syntactic correctness of the merged programs . Several syntactic program merge techniques have been proposed ( Westfechtel , 1991 ; Asklund , 1999 ) which are based on parse trees or abstract syntax trees and graphs . Apel et al . noted that structured and unstructured merge each has strengths and weaknesses . They developed a semi-structured merge tool , FSTMERGE , which switches between approaches ( Apel et al. , 2010 ) . They later introduced JDIME , an approach that automatically tunes a mixture of structured and unstructured merge based conflict locations ( Apel et al. , 2012 ) . AUTOMERGE tool ( Zhu & He , 2018 ) improves upon the JDIME by adding a built-in matcher to check output resolutions for the merges performed by JDIME . AUTOMERGE synthesizes resolutions only when the structured merge algorithm fails to complete a merge . Trindade Tavares et al . ( 2019 ) later implemented jsFSTMerge by adapting an off-the-shelf grammar for JavaScript and modifying the FSTMerge algorithm itself to address JavaScript specific issues . In addition , Pan et al . ( 2021 ) explore using program synthesis to learn repeated merge resolutions within a project . However , the approach is limited to a single C++ project , and only deals with restricted cases of import statements . Sousa et al . ( 2018 ) explore the use of program verification to certify that a merge obeys a semantic correctness criteria , but does not help resolve merge conflicts . 2 MOTIVATING EXAMPLE . In this section , we formulate the traditional line-level merge conflict resolution problem as a classification task and show how token-level formulation of diff3 helps to localize the merge conflicts . Fig . 1 provides an example merge conflict in JavaScript . Fig . 1 ( a ) on the left shows the standard diff3 markers “ < < < < < < < A.js ” , “ ||||||| O.js ” , “ ======= ” and “ > > > > > > > B.js ” , which denote the conflicting regions introduced by programs A , base O , and B respectively . Here , O represents the most common ancestor of programs A and B in the version control history . We denote the program text of diff3 conflicting regions as Aj , Bj , Oj , where j is a conflict index . The conflict index may be omitted when referring to programs consisting of a single conflict only . We refer to the program text outside the conflicting chunks , common to all merged programs versions , as a prefix and suffix , and denote it respectively as Pref and Suff throughout the paper . First , MergeBERT represents each line-level merge conflict instance at token level ( Fig . 1 ( b ) ) which localizes conflicting regions , yielding a ⊂ A , b ⊂ B , o ⊂ O , and then it invokes the neural model to predict a resolution via classification ( Fig . 1 ( c ) ) . Here , and throughout the paper we will use lower case notations to refer to attributes of token-level differencing ( e.g . a , b , and o are conflict regions produced by diff3 of token granularity ) . Intuitively , token diff3 first turns the line-structured text into a list of tokens ( including space and line delimiters ) , applies standard diff3 algorithm to the resulting documents , and reconstructs the merged document at line level . As a result of token-level merge , the whole “ let x = max ( y , ” string is cleanly merged , becoming a part of the program prefix , and “ ) ” is prepended to the program suffix . Token-level diff3 is a syntactic merge algorithm . As such , it does not guarantee semantic correctness of the merged program . In most cases ( 82 % ) , however , token merge matches the user resolution . Observe , that the resolution does not consist of any single line from eitherA orB since both edits modify a common line present in the base . Hence , earlier neural approaches such as DeepMerge ( Dinella et al. , 2021 ) would not be able to synthesize the resolution . On the other hand , structured merge techniques ( such as jsFSTMergeby Trindade Tavares et al . ( 2019 ) ) can not resolve the conflict as the conflict appears on a program statement , which leads to side effects ( e.g . syntactically incorrect code ) . A token-level merge can interleave edits within lines ( i.e. , tokens in which one edit does not conflict with another are trivially merged ) . Consider A ’ s edit of the var to let keyword . Such nonconflicting edits suffice to demonstrate the above . Likewise , consider the token-level conflict for the arguments to the max function : an appropriate model trained on JavaScript should be able to easily deduce that taking the edit from B ( i.e. , `` 11 , z '' ) captures the behavior of A ’ s edit as well . The suggested resolution gives an intuitive demonstration for how MergeBERT turns a complex line-level resolution into a simpler token-level classification problem . MergeBERT can deal with non-trivial real-world merges composed of multiple conflicting chunks . We include a complete example of such a merge conflict in the Appendix . 3 BACKGROUND : DATA-DRIVEN MERGE . Dinella et al . ( 2021 ) introduced the data-driven program merge problem as a supervised machine learning problem . A program merge consists of a 4-tuple of programs ( A , B , O , M ) , where 1 . The base program O is the most common ancestor in the version history for programs A and B , 2. diff3 produces an unstructured line-level conflict when applied to ( A , B , O ) , and 3 . M is the program with the developer resolution , having no conflicts . Given a set of such programs and merges ( A , B , O , M ) , the goal of a data-driven merge is to learn a function , merge , that maximizes the set of examples where merge ( A , B , O ) = M. Moreover , since a program may have multiple unstructured conflicts ( Aj , Bj , Oj , Mj ) , j=0 ... N , the data-driven merge considers the different merge tuples corresponding to the conflicting regions independently , and poses the learning problem over all the merge tuples present in ( A , B , O , M ) . Dinella et al . ( 2021 ) also provide an algorithm for extracting the exact resolution regions for each merge tuple and define a dataset that corresponds to non-trivial resolutions where the developer does not drop one of the changes in the resolution . Further , they provide a sequence-to-sequence encoder-decoder based architecture , where a bi-directional gated recurrent unit ( GRU ) is used for encoding the merge inputs comprising of ( A , B , O ) segments of a merge tuple , and a pointer mechanism is used to restrict the output to only choose from line segments present in the input . Given the restriction on copying only lines from inputs , the dataset defined in the paper did not consider merges where the resolution required token-level interleaving , such as the conflict in Figure 1 . And , lastly , the dataset consists of merge conflicts in a single language , JavaScript . In contrast , our paper addresses both of these limitations .

Summary: This paper presents MergeBERT, a deep model for resolving program merge conflicts in software development. The authors introduce a new, hierarchical differencing and cast the problem as classifying over a fixed set of merge patterns, instead of generating . The model is pre-trained on a large corpus of GitHub code.