Git-Konflikte lösen
Infos für Dozent:
Dies wird mit zwei verschiedenen GitHub-Accounts gezeigt.
- GitHub-Projekt erstellen (
ErsterBenutzer/Repository.git
) - zweiten GitHub-Account als Collaborator hinzufügen
- erster GitHub-Account klont das Projekt auf dem Rechner
Vorher checken: Für den zweiten GitHub-Account muss ein SSH-Key auf GitHub vorliegen und lokal in ~/.ssh/config
angepasst werden:
Host github-other
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_other
IdentitiesOnly yes
Als zweiter GitHub-User das Projekt des ersten Nutzers klonen:
git clone git@github-other:ErsterBenutzer/Repository.git Projektordner
- Lokale Git-Config im Projektordner für zweiten GitHub-Account setzen:
cd projektordner
git config user.name "Anderer Benutzer"
git config user.email "andere-email@example.com"
→ Nun kann der zweite GitHub-Account lokal Änderungen vornehmen und pushen.
Wir spielen nun verschiedene Szenarios durch:
- Änderungen pushen und pullen (ohne Konflikte)
- Änderungen im GitHub-Repo, die noch nicht lokal sind:
- Push schlägt fehl (weil Änderungen im Repo)
- Merge-Strategie in config festlegen
- Pull mit automatischem Merge und anschließenden Push
- Merge-Konflikte behandeln
Änderungen pushen und pullen (ohne Konflikte)
Ablauf:
- Erster Benutzer ändert und committed Datei1 und pusht
- Zweiter Benutzer pullt die Änderungen
- Zweiter Benutzer ändert und committed Datei2 und pusht
- Erster Benutzer pullt die Änderungen
- usw.
→ Keine Konflikte, alles läuft glatt, weil die Änderungen nacheinander geschehen und sich nicht überschneiden.
Änderungen im GitHub-Repo, die noch nicht lokal sind
Ablauf:
- Erster Benutzer ändert und committed Datei1 und pusht
- Zweiter Benutzer ändert und committed Datei2 und versucht zu pushen
→ Push schlägt fehl, weil Änderungen im Repo sind, die noch nicht lokal sind.
- Zweiter Benutzer muss die Änderungen zuerst pullen, bevor er pushen kann.
→ Sowohl im Terminal als auch in VS Code erscheint folgender Fehler:
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:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
Der zweite Benutzer muss die Merge-Strategie festlegen, bevor er pullt.
Wir verwenden git config pull.rebase false
für einen Merge, weil
dies am einfachsten zu verstehen ist.
Im Terminal ausführen:
git config pull.rebase false
Danach klappt das Pullen, und die Änderungen können automatisch gemerged werden, weil sie sich nicht überschneiden. Dennoch ist ein lokaler Commit der Änderungen nötig.
→ Nach dem Commit kann der zweite Benutzer pushen.
→ Änderungen mit git log
anzeigen (Merge branch 'main' of…
)
Das Festlegen der Merge-Strategie muss jedes Teammitglied einmal für das Projekt durchführen.
Merge-Konflikte behandeln
Wir zeigen nun, was passiert, wenn in einer Datei Änderungen vorgenommen werden, die sich überschneiden (z.B. in der Datei README.md
).
- Erster Benutzer ändert
README.md
in Zeile X, committed und pusht - Zweiter Benutzer ändert
README.md
auch in Zeile X und committed dies lokal - Zweiter Benutzer pusht, was fehlschlägt, und pullt die Änderungen
→ Es kommt zu einem Merge-Konflikt, weil die Änderungen sich überschneiden, dazu erscheint folgende Meldung im Terminal:
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
Wir sehen mit git status
folgenden Zustand im lokalen Repository:
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: README.md
Nun müssen wir die Konflikte in der Datei README.md
manuell lösen,
dort werden die Konflikte direkt in der Datei markiert:
Hier steht der Rest des Readme-Textes…
<<<<<<< HEAD
Änderung des zweiten Benutzers
=======
Änderung von Benutzer1
>>>>>>> 893fd404c23f6ee0f04f8693210320e8fa0845cc
Unsere Änderungen (Benutzer2) stehen zwischen <<<<<<< HEAD
und
=======
, die Änderungen des ersten Benutzers zwischen =======
und
>>>>>>>
. Wir müssen die Konflikte manuell auflösen, indem wir die
gewünschten Änderungen in der Datei behalten und den Rest löschen.
Die Markierungen werden auch gelöscht:
Hier steht der Rest des Readme-Textes…
Änderung von Benutzer1
Hier haben wir die Änderungen des ersten Benutzers behalten und die
des zweiten Benutzers gelöscht. Nun können wir mit git add
und
git commit
die Änderungen abschließen.
→ Danach spielen wir das gleiche Szenario in VS Code durch.
In VS Code können wir genau wie im Terminal vorgehen oder die von den Git-Tools bereitgestellten Funktionen nutzen.
Abschließende Bemerkungen
Wir haben nur die wichtigsten Befehle im Umgang mit Git und GitHub kennengelernt, um gemeinsam an einem Projekt zu arbeiten. Es gibt viele weitere Befehle und Möglichkeiten, Git und GitHub zu nutzen. Mehr Infos zu Git:
- Dokumentation bei GitHub: https://docs.github.com/de/get-started/start-your-journey/git-and-github-learning-resources
- Online-Buch “Pro Git”: https://git-scm.com/book/de/v2
- Git-Tutorial (Video, 40 min): https://www.youtube.com/watch?v=uGLQF2kUwOA&t
- ChatGPT und andere KI-Chats können Git erklären und insbesondere Fragen in bestimmten Situationen beantworten.
Es gib viele Tools für die Arbeit mit Git und GitHub, z.B. bietet GitHub auch einen Desktop-Client an. Manche