Drei-Wege-Merge in PhpStorm: Konfliktaufloesung im Detail
AI generated
IDE
{ }
PhpStorm · Git · Merge
Drei-Wege-Merge in PhpStorm
Konfliktaufloesung im Detail verstehen

Git-Konflikte sind kein Grund zur Panik, wenn man den Drei-Wege-Merge-Dialog von PhpStorm einmal wirklich verstanden hat. Base, Local und Remote nebeneinander machen aus einem unuebersichtlichen Diff eine kontrollierbare Entscheidung, Zeile fuer Zeile.

15 Min. Lesezeit Merge-Dialog Base/Local/Remote composer.lock

1. Warum ein Merge-Tool mehr leistet als ein Editor mit Konfliktmarkern

Wer Konflikte direkt in der Datei mit den Markern <<<<<<<, ======= und >>>>>>> loest, kaempft mit zwei Problemen gleichzeitig: Er muss den Konflikt inhaltlich verstehen und gleichzeitig die Textmarker sauber wieder entfernen, ohne versehentlich eine Klammer oder ein Semikolon stehen zu lassen. Genau an dieser Stelle setzt der Drei-Wege-Merge-Dialog von PhpStorm an, denn er trennt die inhaltliche Entscheidung von der mechanischen Aufraeumarbeit vollstaendig voneinander.

Der Dialog zeigt drei Spalten gleichzeitig an: Local links, Base in der Mitte und Remote rechts, dazu eine vierte, editierbare Ergebnisspalte, in der das fertige Resultat entsteht. Diese raeumliche Trennung macht sofort sichtbar, welche Seite welche Aenderung eingebracht hat, statt sich durch ineinander verschachtelte Textmarker zu kaempfen. Fuer PHP-Projekte mit mehreren parallel arbeitenden Entwicklern ist das der entscheidende Unterschied zwischen einem Merge, der in zwei Minuten erledigt ist, und einem, bei dem am Ende ein Syntaxfehler in Produktion landet.

2. Base, Local und Remote richtig lesen

Base ist der gemeinsame Vorfahre, also der Stand der Datei, bevor sich die beiden Branches auseinanderentwickelt haben. Local ist der aktuelle Stand im eigenen Arbeitsverzeichnis, also die eigenen, noch nicht gemergten Aenderungen. Remote ist der Stand des Branches, der gerade gemergt oder gerebast wird, etwa main nach einem git pull oder ein Feature-Branch bei einem Rebase. Diese Zuordnung klingt trivial, wird aber in der Praxis regelmaessig verwechselt, gerade bei einem Rebase, bei dem Local und Remote im Vergleich zu einem normalen Merge vertauscht erscheinen koennen.

PhpStorm markiert Aenderungen gegenueber Base farblich in beiden Aussenspalten, sodass auf einen Blick erkennbar ist, welche Zeilen ueberhaupt vom Konflikt betroffen sind und welche unveraendert geblieben sind. Ein haeufiger Anfaengerfehler ist, die Base-Spalte zu ignorieren, weil sie nicht editierbar ist. Genau sie liefert aber den Kontext, um zu verstehen, ob eine Aenderung eine echte inhaltliche Kollision ist oder ob beide Seiten unabhaengig voneinander dieselbe sinnvolle Korrektur vorgenommen haben.

3. Konflikte teilweise uebernehmen statt Alles-oder-Nichts

Der grosse Vorteil gegenueber einem simplen Accept Yours oder Accept Theirs ist, dass PhpStorm Konflikte nicht als einen einzigen Block behandelt, sondern in einzelne Aenderungs-Chunks unterteilt. Jeder Chunk bekommt eigene Pfeil-Buttons, mit denen genau dieser Ausschnitt aus Local oder Remote in die Ergebnisspalte uebernommen werden kann, ohne die uebrigen Chunks der Datei zu beeinflussen. So laesst sich eine Methode aus dem eigenen Branch behalten und gleichzeitig ein Bugfix aus dem anderen Branch uebernehmen, obwohl beide in derselben Datei liegen.

Die Ergebnisspalte selbst ist ein ganz normaler Editor: Nach der automatischen Uebernahme eines Chunks kann dort frei weitergetippt werden, um zum Beispiel zwei sich widersprechende Parameterlisten manuell zu einer neuen, korrekten Signatur zusammenzufuehren. Das ist der Punkt, an dem sich ein echtes Merge-Tool von einer reinen Kommandozeilen-Loesung absetzt, denn niemand muss die fertige Datei separat oeffnen und nachbearbeiten, alles passiert in einem einzigen Arbeitsschritt.


// Beispiel: Konflikt in einer Repository-Klasse
// Local hat eine neue Methode ergaenzt, Remote hat den Konstruktor erweitert.
// Beides soll erhalten bleiben -- im Ergebnis-Panel manuell zusammenfuehren:

final class ProductAvailabilityChecker
{
    public function __construct(
        private readonly StockRegistryInterface $stockRegistry,
        private readonly LoggerInterface $logger, // aus Remote uebernommen
    ) {
    }

    // Aus Local uebernommen, unveraendert behalten
    public function isAvailable(int $productId): bool
    {
        $stockItem = $this->stockRegistry->getStockItem($productId);
        return $stockItem->getIsInStock();
    }
}

4. composer.lock-Konflikte sinnvoll loesen

Bei composer.lock ist der Drei-Wege-Merge-Dialog fast immer die falsche Ebene, denn die Datei ist ein generiertes Artefakt mit Hash-Pruefsummen, die sich nicht sinnvoll von Hand editieren lassen. Der zuverlaessige Weg ist, den Konflikt in composer.json manuell zu loesen, also die Versionsanforderungen beider Seiten korrekt zusammenzufuehren, und composer.lock anschliessend komplett neu generieren zu lassen, statt die Konfliktmarker in der Lock-Datei selbst aufzuloesen.

In PhpStorm laesst sich composer.lock im Merge-Dialog daher am schnellsten ueber Accept Theirs oder Accept Yours als Platzhalter uebernehmen, um den Konflikt formal aufzuloesen, gefolgt von einem composer update oder composer install im Terminal, das die Datei aus dem korrekten composer.json neu erzeugt. Wer stattdessen versucht, einzelne Paket-Hashes von Hand zusammenzufuehren, produziert fast immer eine Lock-Datei, die nicht mehr zum tatsaechlichen composer.json passt und beim naechsten CI-Lauf mit einem Validierungsfehler auffaellt.

5. package-lock.json und andere generierte Dateien

Fuer package-lock.json in Frontend-Build-Toolchains gilt dieselbe Logik: Der Merge-Dialog eignet sich, um schnell eine der beiden Seiten als Zwischenstand zu waehlen, aber die eigentliche Wahrheit liegt in package.json. Nach der Konfliktaufloesung dort sollte npm install oder der entsprechende Befehl des verwendeten Package-Managers laufen, damit die Lock-Datei wieder konsistent zu den tatsaechlich installierten Versionen ist.

Ein praktischer Kniff in PhpStorm ist, solche generierten Dateien in den Merge-Einstellungen als 'binaer' beziehungsweise ueber .gitattributes mit einem merge=ours oder merge=theirs Treiber zu behandeln, damit sie erst gar nicht im interaktiven Drei-Wege-Dialog auftauchen. So bleibt der Merge-Dialog fuer die Dateien reserviert, bei denen eine inhaltliche Entscheidung tatsaechlich noetig ist, und die Zeit geht nicht fuer das Durchklicken von Hash-Zeilen verloren, die ohnehin gleich wieder neu generiert werden.


# .gitattributes: generierte Lock-Dateien aus dem Merge-Dialog heraushalten
composer.lock merge=ours
package-lock.json merge=ours

# lokal aktivieren (einmalig pro Repository):
git config merge.ours.driver true

# nach dem formalen Konflikt-Abschluss die Lock-Datei neu erzeugen:
composer update --lock
npm install --package-lock-only

6. Zwischen mehreren Konflikten in einem Projekt navigieren

Bei groesseren Merges betreffen Konflikte selten nur eine Datei. PhpStorms Merge-Ansicht listet alle konfliktbehafteten Dateien in einer Uebersicht, bevor der eigentliche Drei-Wege-Dialog fuer die einzelne Datei geoeffnet wird. Aus dieser Liste heraus laesst sich direkt erkennen, ob eine Datei nur einen einzigen kleinen Konflikt oder ein Dutzend verstreute Aenderungen enthaelt, was bei der Priorisierung hilft, mit welcher Datei begonnen wird.

Innerhalb einer einzelnen Datei mit mehreren Konflikt-Chunks bietet der Dialog Navigationspfeile, um direkt zum naechsten oder vorherigen ungeloesten Konflikt zu springen, ohne manuell durch die gesamte Datei zu scrollen. Das ist besonders bei Klassen mit hunderten Zeilen relevant, etwa bei generierten GraphQL-Schema-Dateien oder umfangreichen Konfigurationsklassen, wo ein einzelner uebersehener Konflikt-Chunk sonst leicht unbemerkt in den Commit rutscht.

7. Unterschiede im Dialog zwischen Merge und interaktivem Rebase

Bei einem klassischen git merge entspricht Local dem aktuellen Branch und Remote dem einzufuegenden Branch, was intuitiv der gewohnten Leserichtung entspricht. Bei einem interaktiven Rebase kehrt sich diese Zuordnung faktisch um: Da jeder Commit einzeln auf den Zielbranch aufgesetzt wird, repraesentiert Local oft den Zielbranch und Remote den eigenen Commit, der gerade neu aufgesetzt wird. Wer das nicht beruecksichtigt, uebernimmt beim Rebase leicht versehentlich die falsche Seite als vermeintlich eigene Aenderung.

PhpStorm zeigt bei einem Rebase-Konflikt in der Titelleiste des Dialogs zusaetzlichen Kontext an, etwa den Hash und die Commit-Message des Commits, der gerade angewendet wird. Es lohnt sich, diese Kopfzeile bewusst zu lesen, bevor man vorschnell auf einen der beiden Accept-Buttons klickt, gerade bei laengeren Rebase-Ketten mit vielen Einzelcommits, bei denen sich die Bedeutung von Local und Remote von Commit zu Commit sogar aendern kann.

8. Konflikten mit kleineren Commits und Branch-Hygiene vorbeugen

Der beste Merge-Dialog ersetzt keine gute Branch-Disziplin. Lange laufende Feature-Branches, die wochenlang nicht mit main synchronisiert werden, produzieren fast zwangslaeufig grosse, schwer aufzuloesende Konfliktmengen, weil sich beide Seiten in der Zwischenzeit unabhaengig weiterentwickelt haben. Regelmaessiges Rebasen oder Mergen des Ziel-Branches in den eigenen Feature-Branch haelt die einzelnen Konflikt-Haeppchen klein und damit im Drei-Wege-Dialog schnell ueberschaubar.

Auch die Formatierungseinstellungen im Team spielen eine unterschaetzte Rolle: Wenn zwei Entwickler unterschiedliche PHP-CS-Fixer- oder Code-Style-Konfigurationen verwenden, entstehen Konflikte oft nicht durch inhaltliche Aenderungen, sondern allein durch abweichende Einrueckung oder Zeilenumbrueche. Ein projektweit einheitliches PhpStorm-Codestyle-Schema, ueber .editorconfig oder die geteilte IDE-Konfiguration im Repository verankert, reduziert solche rein kosmetischen Konflikte spuerbar.

9. Praktischer Workflow: Vom Konflikt zum sauberen Commit

In der Praxis bewaehrt sich folgende Reihenfolge: Zuerst die Uebersicht aller konfliktbehafteten Dateien pruefen und generierte Dateien wie Lock-Files gedanklich beiseitelegen. Dann Datei fuer Datei den Drei-Wege-Dialog oeffnen, Base als Referenzpunkt lesen, Chunk fuer Chunk entscheiden und bei Bedarf im Ergebnis-Panel manuell nacharbeiten. Erst wenn alle inhaltlichen Dateien geloest sind, folgen die generierten Lock-Dateien per Neugenerierung.

Vor dem finalen Commit lohnt sich ein Blick in PhpStorms lokale History oder ein kurzer Testlauf, um sicherzustellen, dass die manuelle Zusammenfuehrung nicht versehentlich eine der beiden urspruenglichen Aenderungen unvollstaendig uebernommen hat. Gerade bei PHP-Klassen mit strikten Typen faellt ein vergessener Parameter oder eine fehlende Use-Anweisung oft erst beim naechsten PHPStan-Lauf auf, weshalb ein kurzer Analyse-Durchlauf direkt nach dem Merge Teil der Routine sein sollte.

Situation Empfohlene Aktion Merge-Dialog nutzen? Nachbereitung
Konflikt in PHP-Klasse Chunk fuer Chunk pruefen und im Ergebnis-Panel zusammenfuehren Ja, voll PHPStan/Tests laufen lassen
composer.lock Konflikt formal mit Accept Theirs/Yours aufloesen Nur formal composer update --lock
package-lock.json Konflikt formal aufloesen, Lock-Datei neu erzeugen Nur formal npm install --package-lock-only
Lange laufender Feature-Branch Regelmaessig rebasen statt am Ende einmal mergen Ja, in kleinen Haeppchen Nach jedem Rebase kurz testen
Reine Formatierungs-Konflikte .editorconfig/Codestyle im Team vereinheitlichen Selten noetig Codestyle-Check in CI ergaenzen

Mironsoft

PhpStorm-Setup, Docker-Integration und Team-Produktivität

PhpStorm, das für Magento- und PHP-Projekte wirklich optimal läuft?

Wir prüfen bestehende PhpStorm-Setups auf langsame Indizierung, ungenutzte Docker-Integration und fehlende Team-Konventionen und richten eine Konfiguration ein, die von der ersten Sekunde an produktiv ist.

Setup-Review

Indexing, Interpreter und Speicher-Einstellungen für große Magento-Projekte optimieren.

Docker-Integration

Xdebug, PHPUnit und Datenbank-Tools sauber mit dem Docker-Setup verbinden.

Team-Konventionen

Inspection-Profile, Code-Style und Live-Templates projektweit vereinheitlichen.

10. Zusammenfassung

Drei-Wege-Merge in PhpStorm: Das Wichtigste auf einen Blick

Drei Spalten

Base, Local und Remote werden nebeneinander angezeigt, dazu eine editierbare Ergebnisspalte fuer das fertige Resultat.

Chunk-weise Kontrolle

Jeder Konflikt-Ausschnitt kann einzeln aus Local oder Remote uebernommen werden, kein Alles-oder-Nichts.

Lock-Dateien anders behandeln

composer.lock und package-lock.json formal aufloesen und danach automatisch neu generieren lassen.

Rebase beachten

Bei einem interaktiven Rebase koennen sich Local und Remote im Vergleich zum normalen Merge vertauschen.

11. FAQ: Drei-Wege-Merge in PhpStorm: Das Wichtigste auf einen Blick

1Was bedeuten Local, Base und Remote im PhpStorm-Merge-Dialog genau?
Base ist der gemeinsame Vorfahre der Datei vor der Trennung der Branches. Local ist der aktuelle eigene Arbeitsstand. Remote ist der Stand des Branches, der gerade eingemergt oder aufgerebast wird. Bei einem Rebase kann sich die Zuordnung von Local und Remote im Vergleich zu einem normalen Merge vertauschen.
2Kann ich einen Konflikt nur teilweise aus einer Seite uebernehmen?
Ja. PhpStorm zerlegt jeden Konflikt in einzelne Aenderungs-Chunks mit eigenen Pfeil-Buttons. So laesst sich pro Chunk entscheiden, ob Local, Remote oder eine manuelle Kombination im Ergebnis-Panel landet, statt die gesamte Datei einheitlich zu uebernehmen.
3Warum sollte ich composer.lock nicht direkt im Merge-Dialog editieren?
composer.lock enthaelt generierte Hash-Pruefsummen, die sich nicht sinnvoll von Hand zusammenfuehren lassen. Besser ist es, den Konflikt in composer.json zu loesen und composer.lock danach per composer update neu erzeugen zu lassen.
4Wie gehe ich mit package-lock.json-Konflikten in Hyva-Projekten mit Tailwind-Build um?
Genauso wie bei composer.lock: package.json manuell konfliktfrei machen, den Konflikt in package-lock.json formal ueber Accept Theirs oder Yours aufloesen und die Datei danach mit npm install neu generieren lassen, damit sie zur tatsaechlichen Abhaengigkeitsstruktur passt.
5Wie finde ich alle konfliktbehafteten Dateien nach einem Merge schnell?
PhpStorm zeigt nach einem gescheiterten Merge oder Rebase eine Uebersicht aller betroffenen Dateien. Von dort aus laesst sich direkt in den Drei-Wege-Dialog jeder einzelnen Datei springen, ohne die Kommandozeile bemuehen zu muessen.
6Kann ich innerhalb einer Datei zwischen mehreren Konflikten springen?
Ja. Der Merge-Dialog bietet Navigationspfeile, um direkt zum naechsten oder vorherigen ungeloesten Konflikt-Chunk zu springen. Das erspart manuelles Scrollen durch lange Dateien mit verstreuten Konfliktstellen.
7Wie kann ich Lock-Dateien ganz aus dem interaktiven Merge-Dialog heraushalten?
Ueber .gitattributes lassen sich Dateien wie composer.lock mit einem merge=ours-Treiber versehen, kombiniert mit git config merge.ours.driver true. Danach werden solche Dateien bei Konflikten automatisch behandelt und tauchen nicht mehr im interaktiven Dialog auf.
8Warum entstehen bei mehreren Entwicklern so viele reine Formatierungs-Konflikte?
Wenn im Team unterschiedliche Codestyle-Einstellungen aktiv sind, veraendern sich Einrueckung oder Zeilenumbrueche unabhaengig vom eigentlichen Code. Eine gemeinsame .editorconfig oder ein geteiltes PhpStorm-Codestyle-Schema reduziert solche kosmetischen Konflikte deutlich.
9Was sollte ich direkt nach einem geloesten Merge-Konflikt in PHP-Code tun?
Einen kurzen PHPStan-Lauf oder die relevanten Tests ausfuehren. Gerade vergessene Parameter, fehlende Use-Anweisungen oder inkonsistente Typen fallen bei einer manuellen Zusammenfuehrung im Ergebnis-Panel sonst erst spaeter auf.
10Hilft haeufigeres Rebasen wirklich gegen grosse Konfliktmengen?
Ja. Je laenger ein Feature-Branch unabhaengig von main weiterlaeuft, desto groesser und unuebersichtlicher werden Konflikte am Ende. Regelmaessiges Rebasen haelt einzelne Konflikt-Haeppchen klein und im Drei-Wege-Dialog leicht handhabbar.