Git-Tutorial: Branches, Merge und Konflikte im Team
geprüft am 7 September 2026 · 10 Min.
Leg mit git switch -c nom einen Branch an, arbeite, und merge ihn dann vom Zielbranch aus mit git merge. Bei einem Konflikt setzt Git Marker in die Datei: schreib den richtigen Inhalt, entferne die Marker, dann git add und git commit. git merge --abort macht jederzeit alles rückgängig.
Ein Branch ist eine parallele Entwicklungslinie. Mit ihm arbeitest du an einem Feature, ohne die stabile Version anzufassen, und dein Kollege macht auf seiner Seite dasselbe. Dieses Kapitel deckt den kompletten Zyklus ab: einen Branch anlegen, ihn mergen, einen Konflikt von Hand lösen und zwischen merge und rebase wählen.
git switch statt git checkout
Historisch war git checkout für alles zuständig: den Branch wechseln, einen neuen anlegen, eine Datei wiederherstellen, auf einen bestimmten Commit springen. Diese Häufung von Rollen ist bei Einsteigern die häufigste Ursache für Verwirrung und bei allen anderen für Unfälle.
Git 2.23 vom August 2019 hat den Befehl in zwei geteilt: git switch für den Wechsel zwischen Branches, git restore zum Verwerfen von Änderungen. Bei ihrem Erscheinen galten beide als experimentell, in der offiziellen Dokumentation tun sie das nicht mehr. Dieses Kapitel benutzt sie und nennt jedes Mal die Entsprechung mit checkout, die dir in Tutorials und auf Stack Overflow noch lange begegnen wird.
| Ziel | Moderner Befehl | Alte Form |
|---|---|---|
| Den Branch wechseln | git switch nom | git checkout nom |
| Einen Branch anlegen und hineinwechseln | git switch -c nom | git checkout -b nom |
| Zurück zum vorigen Branch | git switch - | git checkout - |
| Die Änderung an einer Datei verwerfen | git restore fichier | git checkout -- fichier |
| Eine Datei aus dem Index nehmen | git restore --staged fichier | git reset HEAD fichier |
Einen Branch anlegen und darin arbeiten
git switch -c feature/panierSwitched to a new branch 'feature/panier'Der Branch startet an dem Commit, auf dem du gerade standest. Du kannst jetzt normal ändern, hinzufügen und committen: nichts davon taucht auf main auf, solange du es nicht gemergt hast.
Für Branch-Namen schreibt Git keine Regel vor, aber die Präfixe feature/, fix/ und hotfix/ sind eine verbreitete Konvention, und die Oberflächen der Hoster gruppieren sie sichtbar.
Um zu sehen, wo du stehst:
git branch # die lokalen Branches
git branch -vv # mit dem letzten Commit und dem verfolgten Remote-Branch
git branch -a # lokale und entfernte
git switch - # zurück zum vorigen BranchUm den Branch zu veröffentlichen und ihn dem Team sichtbar zu machen:
git push -u origin feature/panierDen Branch eines Kollegen holen
In der Gegenrichtung bringt git fetch deinen Kenntnisstand über den Server auf den neuesten Stand, ohne an deinen Branches etwas zu ändern:
git fetch origin feature/collegue # einen bestimmten Branch
git fetch --all # alle Remote-Repositories
git branch -r # was du vom Server weißt origin/HEAD -> origin/main
origin/feature/collegue
origin/mainJetzt musst du nur noch hineinwechseln. Git legt den lokalen Branch automatisch an und verknüpft ihn mit dem des Servers:
git switch feature/colleguebranch 'feature/collegue' set up to track 'origin/feature/collegue'.
Switched to a new branch 'feature/collegue'Wenn Git den Branch-Wechsel verweigert
Das ist einer der ersten Fehler, die dir begegnen werden:
error: Your local changes to the following files would be overwritten by checkout:
index.html
Please commit your changes or stash them before you switch branches.
AbortingGit schützt deine Arbeit: die Datei, die du geändert hast, hat auf dem anderen Branch einen anderen Inhalt, und der Wechsel würde sie überschreiben. Drei Lösungen, nach Vorzug geordnet.
Committen, wenn die Arbeit in sich stimmig ist. Das ist fast immer die richtige Antwort, ein unfertiger Commit auf einem Arbeitsbranch kostet nichts und lässt sich später mit den Befehlen zum Rückgängigmachen aus dem vorigen Kapitel korrigieren.
Beiseitelegen, wenn die Arbeit halb fertig ist:
git stash # legt die Änderungen beiseite
git switch main # …du erledigst, was zu erledigen war…
git switch -
git stash pop # holt die Änderungen zurückSaved working directory and index state WIP on main: 6d495d9 Page d accueilWegwerfen, mit git restore ., wenn die Änderungen nichts taugten. Ohne Rückweg.
Einen Branch mergen
Ist das Feature fertig, wechsel auf den Zielbranch und merge:
git switch main
git merge feature/panierHaben die beiden Branches unterschiedliche Dateien geändert, erledigt Git die Zusammenführung allein und muss dich nichts fragen. Interessant ist der andere Fall.
Einen Konflikt lösen
Hier die Situation, die für dieses Kapitel nachgestellt wurde. Auf feature/panier wurde die zweite Zeile von index.html durch eine Meldung über den leeren Warenkorb ersetzt. Auf main wurde die erste Zeile geändert, um den Markennamen zu ergänzen. Beide Branches haben dieselbe Datei angefasst.
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.Nichts ist kaputt. Git hat zusammengeführt, was ging, und überlässt dir den Rest. Als Erstes fragst du, wo du stehst:
git statusOn branch main
Your branch is ahead of 'origin/main' by 1 commit.
(use "git push" to publish your local commits)
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")Nur die Liste der zu bearbeitenden Dateien:
git diff --name-only --diff-filter=UÖffne die Datei. Git hat dort Marker eingefügt:
<<<<<<< HEAD
<h1>Boutique Gekkode</h1>
<p>Bienvenue sur la boutique.</p>
=======
<h1>Boutique</h1>
<p>Votre panier est vide.</p>
>>>>>>> feature/panierDas liest sich mechanisch. Zwischen <<<<<<< HEAD und ======= steht die Version des Branches, auf dem du bist, hier main. Zwischen ======= und >>>>>>> steht die Version des Branches, den du mergst.
Das richtige Ergebnis schreibst du selbst. Es ist nicht zwingend die eine oder die andere Fassung: hier sind beide Änderungen gut und müssen nebeneinander bestehen bleiben.
<h1>Boutique Gekkode</h1>
<p>Votre panier est vide.</p>Lösch die drei Marker, sie dürfen nicht in der Datei bleiben. Sag Git dann, dass die Sache erledigt ist, und schließ den Merge ab:
git add index.html
git commit -m "Fusionne feature/panier dans main"* 0899b0c Fusionne feature/panier dans main
|
| * aacf4c0 Panier : message quand le panier est vide
* | 11ff16b Ajoute le nom de la marque au titre
|/
* 6d495d9 Page d accueilDer Merge-Commit hat zwei Elternteile, und der Graph macht das sichtbar.
Alles abbrechen und neu ansetzen
Wächst dir der Konflikt über den Kopf, bist du zu nichts verpflichtet:
git merge --abortDas Repository steht wieder genau so da wie vor dem Befehl merge. Nichts ist verloren, du kannst später neu anfangen oder die Sache mit dem Autor des anderen Branches besprechen.
merge oder rebase
Beide binden die Arbeit eines Branches in einen anderen ein, aber nicht auf dieselbe Weise.
git merge legt einen Merge-Commit an, der die beiden Historien verbindet. Die Historie behält die genaue Spur dessen, was passiert ist, einschließlich der Tatsache, dass zwei Branches parallel existiert haben. Der Graph ist getreu, aber er verzweigt sich.
git rebase spielt deine Commits über dem Zielbranch neu ein, als hättest du von dessen letzter Version aus gearbeitet. Die Historie bleibt eine gerade Linie und ist leichter zu lesen, aber sie wird umgeschrieben: deine Commits bekommen neue IDs.
git switch feature/panier
git rebase mainEin Rebase kann auf dieselben Konflikte stoßen wie ein Merge, Commit für Commit. Die Lösung ist identisch, nur der Befehl zum Weitermachen unterscheidet sich:
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
error: could not apply 4937109... Promo
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Could not apply 4937109... Promogit add index.html
git rebase --continue
# oder, um alles abzubrechen
git rebase --abortDie goldene Regel passt in einen Satz: rebase nie einen Branch, den andere schon geholt haben. Eine geteilte Historie umzuschreiben zwingt deine Kollegen dazu, ihre eigene von Hand zu reparieren. Auf deinem eigenen Arbeitsbranch dagegen, bevor du ihn anbietest, ist ein Rebase völlig legitim und liefert eine deutlich lesbarere Historie.
Der Alltagsfall: jemand hat vor dir gepusht
Du willst pushen, und Git verweigert es:
To /root/o.git
! [rejected] main -> main (fetch first)
error: failed to push some refs to '/root/o.git'
hint: Updates were rejected because the remote contains work that you do notDer Server hat Commits, die du nicht hast. Du musst sie zuerst einbinden. Und an dieser Stelle stellt dir Git auf einem frischen Repository eine Frage, statt zu handeln:
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint: git config pull.rebase false # merge
hint: git config pull.rebase true # rebase
hint: git config pull.ff only # fast-forward only
hint:Seit Version 2.27 weigert sich Git, an deiner Stelle zu wählen. Beantworte die Frage ein für alle Mal, wie im Installationskapitel vorgeschlagen:
git config --global pull.rebase trueDer Ablauf sieht dann so aus:
git pull --rebase
git pushFrom /root/o
622a60b..38b7dc5 main -> origin/main
Rebasing (1/1)Successfully rebased and updated refs/heads/main.
* 5b45117 Ajoute app.js
* 38b7dc5 Ajoute la doc
* 622a60b DepartDein Commit wurde über den des Kollegen gesetzt, und die Historie ist linear geblieben, ohne störenden Merge-Commit. Das ist die Einstellung, die sich für ein Team am Anfang empfiehlt.
Zum Schluss eine Warnung: versuch nie, einen abgelehnten push mit git push --force durchzudrücken. Dieser Befehl überschreibt die Arbeit, die auf dem Server liegt. Musst du wirklich forcieren, nach einem Rebase deines eigenen Branches, dann nimm git push --force-with-lease: es weigert sich, Commits zu überschreiben, die du noch nicht gesehen hattest.
Aufräumen
Ein zusammengeführter Branch hat keinen Grund mehr zu existieren. Wurde er mit -u veröffentlicht, pushen Sie zuerst seine letzten Commits: Git weigert sich, einen lokalen Branch zu löschen, der seinem Remote-Branch voraus ist, selbst wenn er in main gemergt ist.
git push origin feature/panier
git branch -d feature/panierDeleted branch feature/panier (was bc2203a).Ohne diesen vorherigen push ist die Meldung eindeutig:
warning: not deleting branch 'feature/panier' that is not yet merged to
'refs/remotes/origin/feature/panier', even though it is merged to HEAD
error: the branch 'feature/panier' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D feature/panier'
hint: Disable this message with "git config set advice.forceDeleteBranch false"Wurde der Branch nicht gemergt, stoppt Git dich, was ein nützliches Sicherheitsnetz ist:
error: the branch 'feature/promo' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D feature/promo'
hint: Disable this message with "git config set advice.forceDeleteBranch false"Um den Branch auch auf dem Server zu löschen und die lokal überflüssig gewordenen Referenzen aufzuräumen:
git push origin --delete feature/panier
git fetch --prunegit fetch holt den Stand des Servers, ohne etwas in deine Branches zu mergen, anders als git pull. Die Option --prune entfernt dabei die Remote-Branches, die es nicht mehr gibt, also die, die deine Kollegen gemergt und gelöscht haben.
Du kannst jetzt zusammenarbeiten. Das letzte Kapitel behandelt die Organisation: welches Branch-Modell zu deinem Team passt.
Häufige Fehler
git stash beiseite, bevor du den Branch wechselst.git pull, allein zwischen Merge und Rebase zu wählen. Klär die Frage mit git config --global pull.rebase true.git pull --rebase ein. Nimm nie git push --force, um dich darüber hinwegzusetzen: es überschreibt die Arbeit der anderen.<<<<<<<, ======= und >>>>>>> beginnen, müssen vor dem git add aus der Datei verschwinden.