Skip to content

Repository files navigation

Refactoring and Merge Effort

This project aims to analyze the relationship between the occurrence of refactorings and the merge effort.

Getting Started

Prerequisites

This project requires Python, pygit2, libgit2, Mysql and RefactoringMiner, and it was tested on the following versions:

python==3.6
pygit2==0.27.0
libgit2==0.27.0
mysql==8.0.23
RefactoringMiner==2.1

Preparing the runtime environment:

Install libgit2/pygit2

First of all, if you are using Mac OS or Linux you need to install libgit2. If you have Anaconda installed in your computer, you can simple do:

$ conda install -c conda-forge libgit2

Otherwise, on Mac OS you can install libgit2 using homebrew:

$ brew install libgit2

On Linux you can install the latest version of libgit2 by doing:

$ wget https://github.com/libgit2/libgit2/archive/v0.27.0.tar.gz
$ tar xzf v0.27.0.tar.gz
$ cd libgit2-0.27.0/
$ cmake .
$ make
$ sudo make install
$ sudo ldconfig

For more information http://www.pygit2.org/install.html

Install Mysql

  1. Open the terminal and run the following command:
sudo apt update
  1. Enter your password and wait for the update to finish.

  2. Next, run:

sudo apt upgrade
  1. Install
sudo apt install mysql-server

Install RefactoringMiner

We are using version 2.1 of RefactoringMiner. More details about the tool and installation steps can be found at: https://github.com/tsantalis/RefactoringMiner.

Clone Refactoring-Merge Project

URL: https://github.com/gems-uff/refactoring-merge.git.

Create the Database

The script for creating the database in mysql can be found in the file "script_database.sql" in the output folder of this project.

Basic Usage

Mining repositories on GitHub

Mining cloned repositories must be carried out in three steps: collecting branches, collecting code refactorings, and calculating the merge effort. The script that collects the branches must be the first to be executed. The other scripts are independent and can be executed in any order.

Script 1 - Collect Branches

./script_1_colllect_branches.py --database [data_base_name] --repo_path [local_repository_path]

Parameters:

--database = (mandatory) database name.
--repo_path = (mandatory) local path to where the Git project repository was cloned.
--log = (optional) boolean parameter indicating the need to print the execution log.
--retry (optional) boolean parameter indicating the need to retry the execution. This retry is only applicable when the repository is updated via git pull.

Script 2 - Collect Refactorings

./script_2_collect_refactorings.py --database [data_base_name] --repo_path [local_repository_path] --refminer_path [refminer_path] --arq_ref_miner [refminer_path_output_file] 

Parameters:

--database = (mandatory) database name.
--repo_path = (mandatory) local path to where the Git project repository was cloned.
--refminer_path = (mandatory) Refactoring Miner tool executable code path.
--arq_ref_miner = (mandatory) .json file name that will store the results returned by the Refactorings Miner tool.
--log = (optional) boolean parameter indicating the need to print the execution log.
--retry (optional) boolean parameter indicating the need to retry the execution. This new attempt is applicable in cases of interruptions in script execution or in Refactoring Miner timeout situations.

Script 3 - Calculate Merge Effort

./script_3_calculate_merge_effort.py --log --database [data_base_name] --repo_path [local_repository_path]

Parameters:

--database = (mandatory) database name.
--repo_path = (mandatory) local path to where the Git project repository was cloned.
--log = (optional) boolean parameter indicating the need to print the execution log.
--retry (optional) boolean parameter indicating the need to retry the execution. This new attempt is applicable in cases of interruptions in the execution of the script or in situations of timeout in the effort calculation.

Merge Effort Computation

The merge effort is computed by comparing the changes introduced in the merge commit with the changes performed independently in each branch, using a set-based formulation over code differences.

Definitions

Let:

  • $C_{base}$: the common ancestor of the merge.
  • $C_{merge}$: the merge commit.
  • $C_{p1}, C_{p2}$: the parent commits of the merge.

Calculations

We compute the sets of actions as follows:

  1. Actions introduced by the merge:

    • $$A_{merge} = \text{diff}(C_{base}, C_{merge})$$
  2. Actions performed in each branch:

    • $$A_{b1} = \text{diff}(C_{base}, C_{p1})$$
    • $$A_{b2} = \text{diff}(C_{base}, C_{p2})$$
  3. Total actions from both branches (union):

    • $$A_{branches} = A_{b1} \cup A_{b2}$$
  4. Additional actions introduced during merge resolution:

    • $$A_{extra} = A_{merge} \setminus A_{branches}$$

Final Metric

The Merge Effort is defined as the cardinality (size) of the extra actions set:

  • $$\text{effort} = |A_{extra}|$$

Note: This value represents the number of lines added or removed during the merge process that cannot be directly explained by the independent evolution of the branches—essentially measuring the manual work required to reconcile concurrent changes.

Conceptual model of the database used to store the data collected by the mining scripts

The figure below presents a simplified version of the conceptual model, summarizing the structure of the database used to store both collected and computed data. The data collection and processing are organized into a three-stage mining pipeline implemented through three scripts. Script S1 iterates over each selected repository, identifies merge commits and the commits contained in their respective branches, collects relevant project-level metadata, and stores this information in the relational database (tables Project, Commit, MergeBranch, and MergeCommit). Script S2 traverses all commits in the branches of each merge commit, extracts detailed information about refactorings using RefactoringMiner v3.1, and stores the refactoring type and code locations in the Refactoring table. Script S3 computes the merge effort for each merge commit and stores the resulting values in the corresponding attributes of the MergeCommit table. Scripts S2 and S3 are independent and can be executed in any order, as they analyze different aspects of the collected data.

Conceptual Model

Building the Dataset

To build the dataset for the application of the data mining technique (extraction of association rules) just run the script "extract_merge_commits_score.py":

./extract_merge_commits_score.py --branches --selected_refactorings --datasetname ['datasetname.csv']

Parameters:

--branches = (optional) boolean parameter indicating the need to split refactoring attributes into two branches (b1 and b2). When not informed, the script will sum the total of refactorings of each type in the two branches.
--selected_refactorings = (optional) boolean parameter indicating the need to compute only selected refactorings. When informed, the script will only consider the 33 types of refactorings considered in this study.
--datasetname = (optional) name of the produced dataset. When not informed, the script will save in the "output" folder a csv file with the following name: "merge_refactoring_ds.csv"

Association Rule Extraction using Apriori Algorithm

In this stage, we implemented algorithms for extracting association rules using Python within the Google Colab environment. The process focuses on identifying co-occurrence patterns between sets of items.

Environment and Dependencies

To execute the scripts, the apyori library must be installed:

Important

Installation: !pip install apyori
Documentation: PyPI - apyori


Google Colab Notebooks

You can access the full implementations through the following links:


Evaluation Metrics

A rule $X \rightarrow Y$ indicates, with a certain assurance, that antecedent $X$ implies consequent $Y$. We evaluate rule relevance using three primary measures:

1. Support

Measures the percentage of instances in the dataset $D$ that satisfy both the antecedent and the consequent.

$$Sup_{(X \rightarrow Y)} = \frac{T_{X \cup Y}}{T}$$

Where $T_{X \cup Y}$ is the number of records containing both $X$ and $Y$ , and $T$ is the total number of records.

2. Confidence

Measures the probability of the consequent occurring given the occurrence of the antecedent.

$$Conf_{(X \rightarrow Y)} = \frac{T_{X \cup Y}}{T_X}$$

Where $T_X$ is the number of records satisfying the antecedent $X$.

3. Lift

Shows how much more frequently $Y$ occurs when $X$ is present compared to its general occurrence. It is calculated by dividing the rule's Confidence by the Support of the consequent.

$$Lift_{(X \rightarrow Y)} = \frac{Conf_{(X \rightarrow Y)}}{Sup_{(Y)}}$$

Lift Interpretation:

  • Lift = 1: Indicates conditional independence; $X$ does not affect the occurrence of $Y$.
  • Lift > 1: Positive dependence ($X$ increases the probability of $Y$).
  • Lift < 1: Negative dependence ($X$ reduces the probability of $Y$).

Note: Support and Confidence act as filters; only rules meeting the minimum input thresholds are extracted.

Project corpus and dataset used in our latest study

Our latest study evaluated 64 open-source projects. The table below shows the characteristics of the projects selected for analysis, presenting the number of commits (NC), the number of merge commits (NMC), the number of merge commits using the --no-ff flag (NMC-off), and the number of valid merge commits (NVMC). The final version of the dataset discarded about 28.3% of the merges because they were generated by the Git command --no-ff, resulting in 91,270 merge commits.

The study were conducted with 64 open-source projects between May 2025 and July 2025.

This folder contains two compressed .csv files: ds_os_join.csv and ds_os_split.csv (available in this repository - folder project-corpus). Each dataset row represents a merge commit and its collected/calculated attributes. In the first one, the total number of refactorings for each type is added without considering the branch on which it was implemented. In the second one, these amounts are separated by branches.

# Project Name Oldest Commit date Newest Commit date NC NMC NMC-nff NVMC
1 Activiti 2012-09-21 2025-06-03 11,696 1,920 682 1,238
2 aeron 2014-02-27 2025-06-03 17,074 957 157 800
3 android-oss 2015-02-21 2025-05-30 5,535 503 119 384
4 AntennaPod 2012-08-16 2025-07-29 8,858 2,323 725 1,598
5 antlr4 2012-01-30 2025-06-05 9,362 1,900 714 1,186
6 baritone 2018-08-01 2025-07-24 4,524 681 176 505
7 byte-buddy 2014-03-08 2025-03-28 7,521 356 117 239
8 camel 2011-03-09 2025-05-10 87,615 584 143 441
9 cas 2011-09-11 2025-05-24 42,344 5,619 764 4,855
10 closure-compiler 2013-06-12 2025-05-30 19,298 446 105 341
11 dbeaver 2015-10-21 2025-06-27 26,242 3,581 385 3,196
12 DependencyCheck 2012-10-30 2025-05-22 10,574 1,791 554 1,237
13 dolphinscheduler 2019-03-28 2025-04-21 9,878 1,351 353 998
14 dropwizard 2011-01-19 2025-07-24 11,363 1,342 620 722
15 druid 2011-11-12 2025-07-24 7,400 1,576 314 1,262
16 dubbo 2012-06-29 2025-05-29 8,913 694 8 686
17 elasticsearch 2011-04-21 2025-06-04 146,438 6,358 1,355 5,003
18 ExoPlayer 2014-07-03 2025-04-27 22,664 900 188 712
19 flink 2010-12-15 2025-07-04 47,108 653 29 624
20 FrameworkBenchmarks 2013-07-24 2025-05-30 14,566 2,507 514 1,993
21 ghidra 2019-03-07 2025-06-03 12,228 4,960 592 4,368
22 gocd 2014-04-15 2025-06-03 18,995 5,114 2,551 2,563
23 graphql-java 2015-07-13 2025-06-02 5,166 928 337 591
24 graylog2-server 2010-06-12 2025-06-03 30,003 1,979 324 1,655
25 hadoop 2009-09-01 2025-06-22 70,650 664 17 647
26 hibernate-orm 2008-08-13 2025-07-06 27,920 297 5 292
27 hive 2013-04-11 2025-06-15 22,158 334 8 326
28 incubator-druid 2012-10-24 2025-07-21 15,966 2,179 612 1,567
29 java-design-patterns 2014-08-13 2025-05-04 4,080 465 167 298
30 jenkins 2009-03-18 2025-06-15 35,612 5,091 660 4,431
31 jna 2010-09-18 2025-04-01 4,237 696 351 345
32 k-9 2008-12-16 2025-06-03 15,124 2,801 1,203 1,598
33 keycloak 2013-07-02 2025-03-20 25,850 4,858 1,856 3,002
34 languagetool 2013-08-08 2025-06-03 77,552 2,544 546 1,998
35 libgdx 2012-06-22 2025-07-22 15,367 2,738 601 2,137
36 lombok 2009-07-17 2025-05-17 3,756 357 55 302
37 metrics 2010-12-02 2025-02-15 5,206 498 209 289
38 micronaut-core 2017-05-24 2025-05-24 15,131 2,353 248 2,105
39 MinecraftForge 2012-02-17 2025-06-26 9,295 675 263 412
40 mockito 2010-11-21 2025-07-14 6,213 518 250 268
41 mybatis-3 2013-02-23 2025-05-31 5,259 1,296 757 539
42 mybatis-plus 2016-01-25 2025-05-30 5,981 709 180 529
43 nacos 2018-07-21 2025-06-02 5,413 1,131 342 789
44 NewPipe 2015-09-11 2025-05-25 11,226 2,196 572 1,624
45 okhttp 2012-07-23 2025-04-24 6,223 1,948 1,124 824
46 onedev 2012-06-01 2025-06-02 5,918 384 27 357
47 openapi-generator 2011-07-30 2025-05-27 23,499 2,911 739 2,172
48 OpenRefine 2010-05-27 2025-05-21 8,801 1,163 385 778
49 pentaho-kettle 2011-07-07 2025-06-03 30,304 6,742 2,720 4,022
50 pinpoint 2014-07-05 2025-07-28 14,677 1,968 999 969
51 realm-java 2012-04-23 2025-07-13 10,710 3,455 842 2,613
52 redisson 2013-12-22 2025-06-02 9,330 1,415 193 1,222
53 robolectric 2010-06-28 2025-05-17 14,758 3,910 1,240 2,670
54 RxJava 2012-04-09 2025-07-18 7,570 1,566 678 888
55 shardingsphere 2016-01-18 2025-04-03 42,603 2,793 658 2,135
56 skywalking 2015-11-07 2025-02-19 8,086 991 379 612
57 SmartTubeNext 2020-10-16 2025-05-30 9,736 1,829 780 1,049
58 smile 2014-11-22 2025-05-23 3,873 354 75 279
59 sonarqube 2011-01-11 2025-03-07 37,111 622 16 606
60 spring-framework 2009-09-18 2025-06-03 35,936 2,571 938 1,633
61 swagger-core 2011-07-29 2025-05-13 4,882 1,277 716 561
62 thingsboard 2016-12-01 2025-07-27 19,051 5,400 764 4,636
63 vert.x 2011-07-14 2025-05-27 11,504 1,413 403 1,010
64 zaproxy 2012-05-07 2025-05-31 9,544 3,121 1,582 1,539
- Totals - - 1,281,477 127,256 35,986 91,270

Open-Source Project Inspection Examples

The examples extracted during the manual inspection of real open-source merge commits are available in the refactoringMergeEffortExamples folder.

Team

  • André Oliveira — Computing Institute, Fluminense Federal University (UFF), Niterói, RJ, Brazil. E-mail: andrelucio@ic.uff.br
  • João Victor Monteiro — Veiga de Almeida University, Brazil. E-mail: jjoaovictormonteiro@gmail.com
  • Vânia Neves — Computing Institute, Fluminense Federal University (UFF), Niterói, RJ, Brazil. E-mail: vania@ic.uff.br
  • Alexandre Plastino — Computing Institute, Fluminense Federal University (UFF), Niterói, RJ, Brazil. E-mail: plastino@ic.uff.br
  • Leonardo Murta — Computing Institute, Fluminense Federal University (UFF), Niterói, RJ, Brazil. E-mail: leomurta@ic.uff.br
  • Bianca Trinkenreich — Colorado State University, Fort Collins, CO, USA. E-mail: bianca.trinkenreich@colostate.edu
  • Alessandro Garcia — Pontifical Catholic University of Rio de Janeiro (PUC-Rio), Rio de Janeiro, Brazil. E-mail: afgarcia@inf.puc-rio.br

License

Copyright (c) 2026 Universidade Federal Fluminense (UFF)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages