Resolve Merge Conflicts in PhpStorm Efficiently
AI generated
IDE
{ }
PhpStorm · Git · Merge Conflicts · Rebase · PHP Teams
Resolve Merge Conflicts in PhpStorm
efficiently with the 3-way merge tool

Resolving merge conflicts in the terminal means manually searching for conflict markers in the file, understanding them, and making a decision, without any visual context. The 3-way merge tool in PhpStorm shows your own version, the incoming version, and the common ancestor at the same time, which makes the decision far easier and reduces mistakes during conflict resolution.

15 min read 3-way merge · Accept Left/Right · Rebase · Magento · composer.lock PhpStorm 2024.x · 2025.x · Git 2.x

1. Understanding merge conflicts: how Git marks conflicts

A Git merge conflict occurs when two branches have changed the same file at the same location in different ways and Git cannot automatically decide which change is correct. Git marks the conflict area with three separators: <<<<<<< HEAD begins your own version (the current branch), ======= separates the two versions, and >>>>>>> feature-branch closes off the incoming version. In between are the conflicting code blocks.

The problem with resolving this manually in the editor: the markers only show the two conflicting versions, not the common starting point (the ancestor). Without the ancestor it is unclear who made which change and why. A developer who only sees the two sides has to guess from context which changes belong together in content and which are truly in conflict. This often leads to one of the changes being accidentally discarded, a bug that is only noticed later when a feature is missing or a regression appears.

2. Opening the 3-way merge tool in PhpStorm

PhpStorm automatically opens the merge tool after a failed merge or rebase in the Git window (View → Tool Windows → Git). In the Local Changes tab or the Conflicts tab, files with conflicts are marked with a red conflict icon. A double click, or right click → Resolve Conflicts, opens the dialog with a list of all conflicting files. For each file, the 3-way merge tool can be opened via Merge.

The tool shows three panels side by side: on the left your own version (the current branch, Local), on the right the incoming version (the branch being merged, Changes from Server or the branch name), and in the middle the result panel, which is initially empty. Above the middle panel, the differences are color coded: green for changes that exist on only one side and can be applied without conflict, blue for parts that were present in the ancestor, and red for real conflicts that must be resolved manually.

3. Step by step: resolving a conflict in the merge tool

The workflow in the PhpStorm 3-way merge tool is systematic: first, apply all non-conflicting changes using Accept Left or Accept Right for the respective sides. PhpStorm recognizes which changes exist on only one side and offers them as individual blocks that are applied to the result panel with a single click on the arrow button. After that, only the real conflicts remain, the red blocks that differ on both sides.

For every real conflict there are three options: Accept Left applies your own version completely, Accept Right applies the incoming version completely, or you edit the result panel manually for a combined solution. Manual editing is the most powerful mode: you see the context on both the left and right and can type exactly what the correct merged code should be into the middle panel. After resolving all conflicts, the result panel is saved and the file is marked as resolved (Apply or Save and Finish).


<?php
// Typical merge conflict in a Magento service class
// Left (Local/HEAD): feature branch has added a new method
// Right (Remote): bugfix branch has changed the constructor

// CONFLICT START, this is how it looks in the editor without the 3-way tool:
<<<<<<< HEAD
    public function __construct(
        private readonly ProductRepositoryInterface $productRepository,
        private readonly StockRegistryInterface $stockRegistry,
        private readonly LoggerInterface $logger,
    ) {
    }

    public function getAvailableProducts(int $categoryId): array
    {
        return $this->productRepository->getList(
            $this->buildSearchCriteria($categoryId)
        )->getItems();
    }
=======
    public function __construct(
        private readonly ProductRepositoryInterface $productRepository,
        private readonly PriceCurrencyInterface $priceCurrency,
        private readonly LoggerInterface $logger,
    ) {
    }
>>>>>>> bugfix/price-currency-fix

// CORRECT SOLUTION in the 3-way merge tool (middle panel):
// Both sides changed the constructor, combine them:
    public function __construct(
        private readonly ProductRepositoryInterface $productRepository,
        private readonly StockRegistryInterface $stockRegistry,    // from Local
        private readonly PriceCurrencyInterface $priceCurrency,    // from Remote
        private readonly LoggerInterface $logger,
    ) {
    }

    // Apply the new method from Local (no conflict on Remote):
    public function getAvailableProducts(int $categoryId): array
    {
        return $this->productRepository->getList(
            $this->buildSearchCriteria($categoryId)
        )->getItems();
    }

4. Magic Resolve: automatically resolvable conflicts

PhpStorm offers the Resolve Simple Conflicts feature (also known as "Magic Resolve"), which can be activated in the conflicts dialog by clicking the corresponding button. The tool analyzes all marked conflict files and automatically resolves conflicts where the two sides made non-overlapping changes in different places in the file. If Local added a method at the beginning of the class and Remote added a method at the end of the class, that is not a real conflict, Git flagged it anyway simply because both branches changed the same file.

Magic Resolve can automatically resolve a significant share of conflicts, so the developer only has to deal with the remaining real conflicts. Important: always check the result of Magic Resolve in the 3-way tool or the diff viewer before the merge is completed. Automatic resolution can, in rare cases, be semantically wrong even though it is syntactically correct.

5. Rebase workflow: conflicts commit by commit

During a rebase, the commits of your own branch are applied one by one onto the target branch. If a commit produces a conflict, the rebase process pauses and PhpStorm shows the conflicts panel. Once the conflict is resolved, the rebase is continued. Compared to a merge, rebase has the advantage that conflicts are resolved in smaller, more understandable units, per commit instead of for all changes at once.

During an interactive rebase (Git → Rebase), PhpStorm shows the current state in the Git window: which commit is currently being applied, which conflicts occurred, and how many commits are still pending. After resolving a conflict, the rebase can be continued with the Continue button without leaving the IDE. The Git log panel immediately shows the updated commit tree after the rebase.


# Git rebase workflow with PhpStorm integration
# Goal: rebase feature-branch onto main

# 1. Start the rebase (Git → Rebase in PhpStorm or in the terminal)
git rebase main

# On conflict, PhpStorm automatically shows the conflicts dialog:
# CONFLICT (content): Merge conflict in app/code/Mironsoft/Catalog/Model/ProductImporter.php
# PhpStorm opens the conflicts panel with resolve options

# 2. After resolving the conflict in the 3-way tool: stage and continue
git add app/code/Mironsoft/Catalog/Model/ProductImporter.php
git rebase --continue
# PhpStorm: Git → Continue Rebase (button in the Git tool window)

# 3. If the rebase commit should be skipped (no meaningful contribution)
git rebase --skip
# PhpStorm: Git → Skip Commit in Rebase

# 4. If the rebase should be aborted (reset everything)
git rebase --abort
# PhpStorm: Git → Abort Rebase

# Best practice for Magento teams:
# rebase feature branches onto main regularly (daily or before a PR)
# regenerate composer.lock on conflicts instead of merging manually:
# bin/composer install  # after resolving the composer.json conflict

6. Typical Magento conflicts: composer.lock, di.xml, and layout XML

In Magento 2 projects, conflicts most commonly arise in three file types. composer.lock is the most frequent source of conflicts: when two developers have installed or updated different packages, the lock file contains thousands of changed lines for each package. The correct solution is not to merge the lock file manually, but to accept one version and then run composer install to regenerate the lock file. In PhpStorm: Accept Left or Accept Right for the entire composer.lock, then run bin/composer install from the terminal or as a run configuration.

The di.xml file contains plugin, preference, and observer configuration. When two branches simultaneously register new plugins for the same type, conflicts arise in the XML structure. This is where the 3-way merge tool is especially valuable: the ancestor shows the state before both changes, making it clear that both new entries need to be included in the result. Layout XML conflicts arise similarly when two branches simultaneously modify the same layout handle, here the order of the XML nodes is often semantically relevant and must be considered carefully.

7. Avoiding conflicts from the start

The best merge conflict strategy is one that prevents conflicts from arising in the first place. Short feature branches with few commits that are rebased onto main frequently have less conflict potential than long branches that have drifted far apart. Feature flags make it possible to merge code that is not yet activated, keeping the branch small without the feature going live prematurely. For Magento: never edit composer.json/composer.lock together in parallel running branches, always perform package installations on main or a dedicated dependency branch.

Clear file ownership within the team reduces conflicts significantly: if team member A is responsible for the Catalog module and team member B for Checkout, conflicts only occur at the interfaces (shared di.xml, layout XML). PhpStorm offers the blame view under Git → Annotate, which shows who last changed which line and when, useful for checking before starting work whether someone else is currently editing the same code.

Conflict type Frequency Recommended solution PhpStorm tool
composer.lock Very frequent Accept one side + composer install Accept Left/Right, then run config
PHP classes Frequent 3-way merge, combine both sides 3-way merge tool
di.xml / layout.xml Frequent Combine both XML blocks 3-way merge with XML syntax highlighting
Tailwind CSS Rare Magic Resolve usually sufficient Resolve Simple Conflicts
JSON configs Medium 3-way merge, then JSON validation Merge tool + IDE validation

8. Merge strategies compared

The choice between merge and rebase influences how conflicts occur and are resolved. With a merge, all conflicts are shown at once, which can be overwhelming for a feature branch with 20 commits and many changed files. With a rebase, conflicts are resolved commit by commit, which makes the context for each conflict clear: you know exactly which specific change caused the conflict. The downside: rebase rewrites commit history and must not be used on public branches that other developers have already checked out.

For Magento teams, a workflow of feature branches + rebase onto main + a merge commit for the PR is recommended: sync regularly during development with git rebase main (small conflicts, clear context), and create a merge commit for the final merge into main (preserving the branch history in the Git log). PhpStorm fully supports this workflow: rebase via Git → Rebase, conflicts via the merge tool, and the final merge via Git → Merge with the --no-ff flag enabled.

Mironsoft

Magento 2 development, Git workflows, and team processes

Want to optimize the Git workflow for your Magento team?

We analyze existing branching strategies, set up rebase workflows, and train teams in efficient merge conflict resolution with PhpStorm, for less merge stress and cleaner commit histories.

Branch strategy

Set up a feature branch workflow and rebase conventions for Magento teams

Conflict prevention

Set up file ownership and composer.lock workflows that minimize conflicts

Team training

Hands-on practice with the 3-way merge tool and rebase workflow on real Magento files

9. Summary

The 3-way merge tool in PhpStorm is the most efficient tool for conflict resolution because it shows not just the two conflicting versions, but also the common starting point. This enables informed decisions instead of guessing. Magic Resolve automatically resolves non-overlapping conflicts and reduces manual effort. The rebase workflow spreads conflicts across smaller, more understandable units, commit by commit instead of all at once.

For Magento teams, the most common sources of conflicts are composer.lock (solution: accept and regenerate), di.xml and layout XML (solution: combine both blocks), and PHP classes where both branches changed the same method or the same constructor (solution: 3-way merge with manual combination). Preventing conflicts early through short branches and frequent rebase synchronization is more effective than resolving them laboriously after the fact.

Merge conflicts in PhpStorm, the essentials at a glance

3-way merge

Left = Local, right = Remote, middle = result. Ancestor context prevents changes from being accidentally discarded. Open via Git → Resolve Conflicts.

Magic Resolve

Resolve Simple Conflicts in the conflicts dialog automatically resolves non-overlapping conflicts. Always check the result in the diff before completing the merge.

composer.lock

Never merge manually. Accept Left or Accept Right for the entire file, then run bin/composer install to regenerate the lock file.

Rebase workflow

Rebase feature branches onto main daily. Resolve conflicts commit by commit. No rebase on public branches that others have already checked out.

10. FAQ: merge conflicts in PhpStorm

1Open the 3-way merge tool in PhpStorm?
Git window → Conflicts tab → right click → Resolve Conflicts → Merge. Opens the tool with Local/Remote/result panels.
2Accept Left vs. Accept Right?
Accept Left = Local version (your own branch). Accept Right = Remote version (branch being merged). Decidable separately for each conflict block.
3What does Magic Resolve do?
Automatically resolves conflicts where both sides changed different, non-overlapping places. Always check the result in the diff.
4Resolve composer.lock conflicts?
Never merge manually. Accept Left or Right for the whole file, then run composer install to regenerate.
5Full rebase in PhpStorm?
Yes. Start Git → Rebase, resolve conflicts in the merge tool, Git → Continue Rebase. No terminal switch needed.
6What is the ancestor in a merge?
The common ancestor commit before the diverging changes. The merge tool uses it to determine which change came from which side.
7Merge or rebase, when to use which?
Rebase for local feature branches (not yet pushed). Merge for the final PR merge into main with --no-ff. No rebase on shared branches.
8Spot conflicting files in PhpStorm?
Red conflict icon in the Git window and in the project tree. After starting a merge, the conflicts dialog appears automatically with the full list.
9Avoiding Magento conflicts?
Short branches, regular rebase. Composer updates only on main. Clear file ownership. Check Git Annotate before editing.
10XML conflicts (di.xml) in the merge tool?
Yes, with XML syntax highlighting in the merge tool. PhpStorm validates well-formedness automatically after the merge.