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.
Inhaltsverzeichnis
- 1. Warum ein Merge-Tool mehr leistet als ein Editor mit Konfliktmarkern
- 2. Base, Local und Remote richtig lesen
- 3. Konflikte teilweise uebernehmen statt Alles-oder-Nichts
- 4. composer.lock-Konflikte sinnvoll loesen
- 5. package-lock.json und andere generierte Dateien
- 6. Zwischen mehreren Konflikten in einem Projekt navigieren
- 7. Unterschiede im Dialog zwischen Merge und interaktivem Rebase
- 8. Konflikten mit kleineren Commits und Branch-Hygiene vorbeugen
- 9. Praktischer Workflow: Vom Konflikt zum sauberen Commit
- 10. Zusammenfassung
- 11. FAQ
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.