RePatch: Refactoring-Aware Patch Integration
- The paper introduces RePatch, a system that inverts refactorings to reconstruct patch contexts and enable asymmetric bug-fix integration across divergent Java variants.
- It extends the RefMerge framework by applying refactoring inversion and transformation replay processes, notably reducing conflict rates observed with standard cherry-pick.
- The system demonstrates practical improvements with a 52.8% resolution rate on previously failing patches while integrating seamlessly into existing Git workflows.
Searching arXiv for RePatch and closely related work to ground the article. Searching arXiv for the specific RePatch paper by title. RePatch is a refactoring-aware, commit-level patch-integration system for Java forks that targets the transfer of bug-fix patches across long-lived, structurally divergent variants. It was introduced as a response to the failure of syntax-based patch application in repositories that have drifted through refactorings such as method renaming, class movement, and code reorganization. The system extends the RefMerge framework, originally designed for symmetric merges, by supporting asymmetric patch transfer: it inverts refactorings in both the source and target to realign patch context, applies the patch, and then replays the transformations so that the target variant retains its intended structure (Ogenrwot et al., 8 Aug 2025).
1. Problem setting: patch transfer under structural drift
In the setting addressed by RePatch, a common ancestor snapshot gives rise to two variants: a source and a target . Over time, these variants diverge not only because of independent bug fixes and feature work, but also because of refactorings. The paper characterizes these long-lived forks as “variants” and emphasizes that bug-fix integration across them is difficult when structural drift obscures semantic correspondence between code elements (Ogenrwot et al., 8 Aug 2025).
The failure mode of conventional tooling is straightforward. A standard git cherry-pick attempts to apply a commit-level diff directly to the target repository, relying on sufficiently similar textual context. When refactorings have renamed methods, moved classes, or otherwise reorganized the abstract syntax tree, the precondition expected by the patch no longer holds. The result is a conflict even when the underlying bug fix remains semantically relevant.
The paper formalizes this setting using refactoring-only transformations from the ancestor to each variant. Let and denote the composite refactoring-only transformations for the source and target, and let denote the bug-fix patch as a semantic transformation on the source. A naive cherry-pick applies directly to , whereas a refactoring-aware approach reconstructs a structurally aligned context before patching. This suggests that the central obstacle is not merely line-level mismatch, but loss of AST-level correspondence induced by refactoring.
2. Formal model: inversion and replay
The core idea of RePatch is expressed as inversion and replay. Rather than forcing the patch onto the current structure of the target, the system temporarily undoes the relevant target-side refactorings, applies the patch in an AST shape closer to the expected context, and then reapplies those refactorings. The paper gives the central formulation as
In this expression, 0 undoes target-side refactorings, 1 applies the bug fix, and 2 restores the target’s intended structure (Ogenrwot et al., 8 Aug 2025).
The source patch itself may also contain refactorings. The paper therefore distinguishes the case in which 3, where 4 represents refactorings bundled into the patch commit and 5 is a pure bug-fix edit. In that setting, RePatch also inverts 6 so that only the core edit is applied in the aligned ancestor-like shape. The corresponding implementation-level realization is
7
so that 8 sees exactly the AST shape it expects.
This formulation clarifies that RePatch is not a general-purpose semantic merge of arbitrary development histories. It is an asymmetric, commit-scoped workflow for transferring a specific bug-fix commit from a source variant into a structurally divergent target while preserving the target’s refactoring intent.
3. System architecture and workflow
RePatch is implemented as a lightweight wrapper around git cherry-pick, augmented with semantic-AST operations borrowed from RefMerge. The architecture has three major components: refactoring inversion, asymmetric patch transfer, and transformation replay (Ogenrwot et al., 8 Aug 2025).
Refactoring inversion detects refactorings in both the target working tree and the source commit using RefactoringMiner. Each detected refactoring is classified as one of a fixed catalog, including examples such as RenameMethod, MoveClass, InlineMethod, and ExtractMethod. For every detected transformation 9, the system computes an inverse 0; for example, if the target contains RenameMethod(m→m′), inversion uses RenameMethod(m′→m). These inversions are then applied to the checked-out Java AST so that the target code shape is brought closer to the patch’s expected context.
Asymmetric patch transfer then uses the ordinary Git mechanism. The target repository is prepared, the source repository is added as a remote, and git cherry-pick --no-commit <patch-hash> is executed to generate the textual diff once the structural mismatch has been reduced by inversion. The paper’s design point is that cherry-pick itself is retained rather than replaced; what changes is the context in which it is invoked.
Transformation replay restores the refactorings after the bug fix has been incorporated. RePatch reapplies the inverted refactorings in the correct dependency order so that the final AST is structurally equivalent to what the target would have become had it received the bug-fix edit before its own refactorings. Ordering constraints are managed through a conflict-matrix imported from RefMerge.
A plausible implication is that RePatch preserves compatibility with existing Git-centered workflows because its semantic reasoning is inserted around, rather than in place of, the familiar cherry-pick operation.
4. Algorithmic realization
The paper presents a high-level integration loop. RePatch first checks out a fresh target head, adds the source as a remote, and fetches the relevant history. It then detects refactorings on both sides: 1 from the current target tree and 2 from the source patch context. After computing inverse transformations 3 and 4, the system applies them to the target AST (Ogenrwot et al., 8 Aug 2025).
At that point, RePatch invokes git cherry-pick --no-commit src/patch_hash under a timeout. If Git still reports conflicts, the attempt is recorded as a failure. Otherwise, the system replays 5 and then 6, commits the integrated result with a generated message, and records success.
The implementation of apply_transformations is heterogeneous. For simple refactorings such as identifier renames and node moves, RePatch uses direct AST rewrites. For more complex transformations, including InlineMethod and ExtractMethod, it uses IntelliJ PSI-based processors. This distinction matters because some refactorings are naturally represented as localized tree edits, whereas others require IDE-grade program transformations with richer semantic support.
The workflow is asymmetric in a precise sense. RefMerge was originally designed for symmetric merges between branches sharing history, whereas RePatch operates on one-sided patch propagation from a source variant into a target variant. The patch is treated as the object of transfer, and the target is semantically reshaped to admit it.
5. Implementation characteristics
RePatch is a Java/Gradle tool that integrates with Git through direct shell calls such as git clone, git remote, and git cherry-pick. It leverages RefactoringMiner for high-precision detection of 17 core refactoring types and uses the IntelliJ IDEA open API for inverting and replaying non-trivial refactorings, including Extract/InlineMethod and PullUp/PushDown (Ogenrwot et al., 8 Aug 2025).
To manage sequencing constraints among refactorings, the tool maintains a conflict-matrix imported from RefMerge. It also imposes a per-patch timeout of 15 minutes by default, after which the case is aborted and classified as a failure. The implementation records detailed logs of detected refactorings, applied inversions, file- and line-level conflicts, and overall success or failure.
The paper also notes several performance optimizations. These include caching ASTs between successive patch attempts on the same target and precomputing RefactoringMiner indices for each variant. These details indicate that RePatch was engineered not only as a proof of concept but also as a repeatable experimental tool for large evaluation campaigns.
Operationally, usage is intentionally simple: a developer clones the target variant, adds the upstream repository as a remote, and runs repatch cherry-pick <upstream-commit>. Under the hood, the system performs the inversion–cherry-pick–replay sequence automatically and commits only if the patch can be applied without conflicts in the aligned AST.
6. Empirical evaluation
The empirical study reused PaReco’s catalog of 364 fork pairs and filtered it to 14 active Java-only pairs as of May 15 2025. PaReco identified 478 “Missed Opportunity” bug-fix pull requests from source to target and vice versa. The baseline for each patch was a git cherry-pick attempt on a fresh checkout of the target head (Ogenrwot et al., 8 Aug 2025).
The baseline failure rate was substantial. Out of 478 attempts, 169 succeeded and 309 failed with conflicts, corresponding to a 64.4% failure rate. The per-project median failure was 94.3%. The paper further reports project-specific examples in prose, including 59% failure on linkedin/kafka across 393 patches and 94.3% on clarin-dspace across 53 patches.
The study then examined whether failed patch applications were associated with refactorings. Running RefactoringMiner on all 309 failures showed that 283 of them, or 91.6%, overlap a refactored entity in the target. The top three refactorings behind failures were RenameMethod at 53.1%, RenameParameter at 41.1%, and MoveClass at 3.5%. These figures support the paper’s central claim that structural misalignment, rather than arbitrary textual divergence, is a dominant source of patch-transfer failure.
For RePatch itself, 17 of the 309 failed baseline patches timed out and were treated as failures, leaving 292 completed RePatch runs. Among those 292 cases, RePatch reduced the number of conflicting files in 155 cases, or 53.1%; increased them in 1.4%; and left them unchanged in 45.5%. At line level, it reduced conflicting LOC in 157 cases, or 53.8%; increased them in 3.4%; and left them unchanged in 42.8%. Most notably, it fully integrated 155 of the 292 previously failing patches, yielding a resolution rate of 52.8%. The paper also provides a concrete example in which a 5-file, 79-line conflict dropped to approximately 20 lines after inversion and replay, resolving 4 of 5 files.
A plausible interpretation is that RePatch is most effective when refactorings preserve enough semantic continuity for inversion to reconstruct the patch precondition, but not when the target has removed or radically reorganized the relevant context.
7. Comparison, limitations, and prospective extensions
The paper compares RePatch primarily against vanilla git cherry-pick and, more qualitatively, against RefMerge. Against syntax-only cherry-pick, RePatch recovers 52.8% of the 64.4% of cases that fail initially. Compared to RefMerge’s symmetric merges, which the paper describes as resolving approximately 25% of conflicts on branches sharing history, RePatch “nearly doubles” conflict resolution in the harder asymmetric setting (Ogenrwot et al., 8 Aug 2025).
Its reported strengths are explicit, rule-based handling of common behavior-preserving edits, traceable logs of refactoring detection and replay, and seamless integration into existing cherry-pick workflows. Equally important are the limitations. RePatch may fail when the target deletes or radically reorganizes the patch context, because AST inversion cannot recreate a missing precondition. Overgeneralized heuristics, such as too-aggressive inlining, can introduce new conflicts in otherwise clean files. Coverage is also bounded by refactoring detection: the paper states that RefactoringMiner misses approximately 8% of subtle refactorings.
The evaluation includes several threats to validity. It is Java-only; 15-minute timeouts, representing 5.5% of cases, are treated pessimistically as failures; and there is no functional test-suite validation after integration. These caveats matter because successful structural integration is not identical to behavioral correctness.
The paper lists several planned extensions: multi-language support via parser-agnostic AST tools such as Tree-sitter, adaptive timeout control, behavioral validation through test suites, incremental refactoring detection for very large codebases, and integration with pull-request automation through CI/CD plugins. This suggests a broader research agenda in semantic-aware maintenance tooling for long-lived variants, with RePatch serving as a specialized system for asymmetric bug-fix propagation in refactoring-heavy Java repositories.