Auflösung divergierender Verläufe: Git Merge vs. Rebase Strategien
Vergleiche Git Merge und Git Rebase für divergierende Branches, Konfliktbehandlung, gemeinsame Historie und Auswahl eines teamfreundlichen Workflows.
Auflösung divergierender Verläufe: Git Merge vs. Rebase Strategien
Git Merge und Rebase helfen beide, wenn Ihr Branch von einem anderen Branch abgewichen ist. Der Unterschied liegt darin, wie sie die Historie bewahren, und die falsche Wahl kann die Zusammenarbeit unnötig erschweren.
Sie brauchen keine perfekte Historie für jede Änderung. Sie brauchen eine Strategie, die Ihr Team versteht und die gemeinsame Branches stabil hält.
Was bedeutet divergierende Historie?
Eine divergierende Historie tritt auf, wenn zwei Branches nach einem gemeinsamen Ausgangspunkt unterschiedliche Commits haben. Zum Beispiel haben Sie am Montag feature/log-cleanup von main erstellt. Am Dienstag hat jemand einen Sicherheitsfix in main gemergt. Jetzt haben Ihr Branch und main jeweils Commits, die der andere nicht hat.
Sie können dies sehen mit:
git log --oneline --graph --decorate --all
Git kann Ihnen auch mitteilen, dass Ihr Branch und der entfernte Branch divergiert sind. Das bedeutet, beide Seiten haben einzigartige Commits. Git erwartet von Ihnen, dass Sie entscheiden, wie sie kombiniert werden.
Die beiden normalen Werkzeuge sind Merge und Rebase:
git merge main
oder:
git rebase main
Beide können den gleichen endgültigen Dateiinhalt erzeugen. Die Historie wird unterschiedlich aussehen.
Wie Git Merge funktioniert
Merge kombiniert Historien, ohne vorhandene Commits umzuschreiben. Wenn Ihr Branch und main beide vorwärts gegangen sind, erstellt Git einen Merge-Commit, der die beiden Arbeitslinien zusammenführt.
Ein typischer Ablauf sieht so aus:
git switch feature/log-cleanup
git fetch origin
git merge origin/main
Wenn es keine Konflikte gibt, erstellt Git einen Merge-Commit oder führt einen Fast-Forward durch, wenn möglich. Bei Konflikten pausiert Git und bittet Sie, diese zu lösen.
Merge ist gut, wenn Sie die wahre Form der Zusammenarbeit bewahren möchten. Es zeigt, dass Arbeiten parallel stattfanden und später kombiniert wurden. Dies kann für langlebige Branches, Release-Branches und gemeinsame Feature-Branches nützlich sein.
Der Nachteil ist, dass häufige Merges Rauschen hinzufügen können. Ein Branch mit vielen "Merge main into feature"-Commits kann schwerer zu durchschauen sein. Das bedeutet nicht, dass es falsch ist, aber es kann die Historie unordentlicher machen.
Verwenden Sie Merge, wenn:
- Der Branch mit anderen Entwicklern geteilt wird.
- Sie das Umschreiben der Commit-Historie vermeiden möchten.
- Ihr Team einen genauen Rekord von Integrationspunkten schätzt.
- Sie einen Release-Branch oder geschützten Branch aktualisieren.
Für einen bereits gepushten und von anderen genutzten Branch ist Merge normalerweise die sicherere Standardeinstellung.
Wie Git Rebase funktioniert
Rebase verschiebt Ihre Branch-Commits, sodass sie auf einem neuen Basis-Commit erscheinen. Anstatt zwei divergierte Linien zu zeigen, die durch einen Merge-Commit verbunden sind, wird die Branch-Historie linear.
Ein typischer Ablauf sieht so aus:
git switch feature/log-cleanup
git fetch origin
git rebase origin/main
Git spielt Ihre Commits nacheinander auf dem neuesten main ab. Wenn ein Konflikt auftritt, stoppt Git bei dem Commit, der nicht abgespielt werden kann. Nach der Behebung des Konflikts fahren Sie fort mit:
git add <fixed-files>
git rebase --continue
Wenn der Rebase verwirrend wird, können Sie abbrechen:
git rebase --abort
Rebase ist nützlich für lokale, private Branches, da es die Historie leicht lesbar hält. Reviewer können Ihre Commits so sehen, als wären sie von Anfang an auf dem neuesten main aufgebaut.
Verwenden Sie Rebase, wenn:
- Der Branch Ihnen gehört und nicht geteilt wird.
- Sie eine saubere, lineare Commit-Historie wünschen.
- Sie einen Branch vorbereiten, bevor Sie einen Pull-Request öffnen.
- Ihr Team explizit rebasierte Feature-Branches bevorzugt.
Die Hauptregel ist einfach: Rebasen Sie keine öffentlichen Commits, es sei denn, Ihr Team erwartet es. Rebase schreibt Commit-Hashes um. Wenn jemand anderes seine Arbeit auf Ihre alten Commits gestützt hat, kann Ihr Umschreiben für sie Verwirrung stiften.
Für weitere alltägliche Git-Historie-Werkzeuge siehe Erkunden der Projekthistorie.
Umgang mit Konflikten während Merge oder Rebase
Konflikte treten auf, wenn Git Änderungen nicht automatisch kombinieren kann. Sie sind häufig in viel genutzten Dateien wie Bereitstellungsmanifesten, Abhängigkeitssperrdateien und gemeinsamen Konfigurationsdateien.
Überprüfen Sie zuerst den Status:
git status
Öffnen Sie die konfliktbehafteten Dateien und suchen Sie nach Konfliktmarkierungen:
<<<<<<< HEAD
current branch version
=======
incoming version
>>>>>>> branch-name
Ihre Aufgabe ist es, den markierten Block durch den endgültigen Inhalt zu ersetzen, den Sie tatsächlich möchten. Behalten Sie die Markierungen nicht.
Nach der Bearbeitung stagen Sie die Datei:
git add path/to/file
Für einen Merge beenden Sie mit:
git commit
Für einen Rebase fahren Sie fort mit:
git rebase --continue
Führen Sie nach der Konfliktlösung Tests oder zumindest den relevanten Validierungsbefehl aus. Eine Datei kann syntaktisch sauber, aber logisch falsch sein. Zum Beispiel können zwei Kubernetes-YAML-Änderungen konfliktfrei mergen, während sie dennoch doppelte Ports oder nicht übereinstimmende Labels definieren.
Auswahl einer Teamstrategie
Die beste Strategie ist die, die eine vorhersagbare Historie für Ihr Projekt schafft. Viele Teams verwenden Rebase für private Feature-Branches und Merge-Commits für Pull-Requests. Andere squashen alle Feature-Arbeit in einen Commit. Einige Infrastrukturteams bevorzugen Merge-Commits, weil sie genau zeigen, wann Branches integriert wurden.
Wählen Sie eine Regel und dokumentieren Sie sie. Eine einfache Richtlinie könnte sein:
- Rebasen Sie Ihren eigenen Feature-Branch vor der Überprüfung.
- Rebasen Sie niemals
main, Release-Branches oder gemeinsame Branches. - Verwenden Sie Merge-Commits für genehmigte Pull-Requests.
- Verwenden Sie Squash-Merge für kleine, einmalige Korrekturen.
Dies verhindert Debatten über Git-Stile während dringender Arbeiten. Es erleichtert auch die Automatisierung, da CI, Release-Notes und Bereitstellungswerkzeuge auf eine konsistente Historie vertrauen können.
Wann man um Hilfe bitten sollte
Fragen Sie, bevor Sie nach einem Rebase auf einem Branch, den andere möglicherweise verwenden, einen Force-Push durchführen. Fragen Sie auch, wenn ein Konflikt Sicherheitseinstellungen, Datenbankmigrationen, Produktionsbereitstellungsdateien oder generierte Sperrdateien betrifft, die Sie nicht verstehen.
Wenn ein Merge oder Rebase verworren wird, stoppen Sie und überprüfen Sie den Zustand mit git status. Sie können normalerweise abbrechen und mit git merge --abort oder git rebase --abort zum vorherigen Zustand zurückkehren. Das ist besser, als zufällige Befehle auszuprobieren, bis der Arbeitsbaum sauber aussieht.
Merge und Rebase lösen das gleiche allgemeine Problem, aber sie erzählen unterschiedliche Geschichten. Merge bewahrt, wie die Arbeit zusammengekommen ist. Rebase erzeugt eine sauberere Linie von Commits. Verwenden Sie jedes dort, wo es passt, und Ihre Git-Historie wird nützlich bleiben, anstatt zu einer Risikoquelle zu werden.