Zwei User ändern zeitgleich das gleiche Projekt und wollen ihren Änderungen committen und pushen.
Es wird davon ausgegangen, dass Java Dateien nicht bei jeder Änderung "sinnlos" verändert werden, z.B. Kopfzeilen ($Revision) und @date. Der Branch ist auf Pull Strategy 'Merge' eingestellt.
Inhalt:
User B ändert eine Datei und committet und pusht diese.
User A ändert nun eine andere Datei und will diese committen und pushen. Der Push schlägt fehl.
Lösung: User A pullt (Rechtsklick 'Team > Pull'). Der Pull führt einen automatischen Merge durch. Ergebnis: 2 Up Pfeil Dekoration. User A kann nun pushen. Fertig.
User B kann nun pullen und sieht dann die Änderungen von User A.
Git ist schlau. Dieser Fall verhält sich wie Fall 1.
User B ändert die Zeile und committet die Datei und pusht.
User A ändert die gleiche Zeile und will diese committen und pushen. Der Push scheitert.
Lösung: User A pullt. Die Datei wird aufgrund eines Merge-Konflikts rot markiert und enthält nun die Zeilen von User A und B samt Merge-Markierungen.
<<<<<<< HEAD // Das hat User A geschrieben. ======= // Das hat User B geschrieben. >>>>>>> branch 'master' of file:///C:\share\pro3-repo
User A stellt fest, dass seine Änderungen richtig sind und die Änderungen von User B verworfen werden müssen. User A ändert dies nun so. Die Merge-Markierungen werden entfernt. Die Datei wird gespeichert. Der händische Merge-Vorgang wird mit Rechtsklick 'Team > Add to Index' abgeschlossen. Nun kann User A diese Änderung committen und pushen. Fertig.
User B kann nun pullen und sieht dann die Änderungen von User A.
Wenn man 'Add to Index' vergisst, dann erfolgt beim Commit die Fehlermeldung 'Repository state: Conflicts'.
Wenn beim 'Commit' die Meldung 'Commit/amend not possible. Possible causes: - No changed items were selected (...)' kommt, dann muss man die Datei geringfügig ändern, damit ein Commit möglich ist. Zum Beispiel ein Leerzeichen ans Zeilenende anfügen. Da Git die Dateiinhalte vergleicht, müssen diese unterschiedlich sein, damit überhaupt committet werden kann.
Beim Branch ist bei beiden Usern die Pull Strategy 'Rebase' (statt 'Merge') eingestellt. Es wird nun der Konfliktfall (Merge Fall 3: User A und B ändern die gleiche Zeile der gleichen Datei mit unterschiedlichem Inhalt) betrachtet.
User B ändert die Zeile und committet die Datei und pusht.
User A ändert die gleiche Zeile und will diese committen und pushen. Der Push scheitert.
Lösung: User A pullt. Die Datei wird aufgrund eines Merge-Konflikts rot markiert und enthält nun die Zeilen von User A und B samt Merge-Markierungen.
<<<<<<< HEAD // Das hat User A geschrieben. ======= // Das hat User B geschrieben. >>>>>>> branch 'master' of file:///C:\share\pro3-repo
User A stellt fest, dass seine Änderungen richtig sind und die Änderungen von User B verworfen werden müssen. User A ändert dies nun so. Die Merge-Markierungen werden entfernt. Die Datei wird gespeichert. Der händische Merge-Vorgang wird mit Rechtsklick 'Team > Add to Index' abgeschlossen. Nun kann User A diese Änderung committen. Anders als bei der Merge-Variante gibt es hier noch nichts zum Pushen. Man muss erst Rechtsklick 'Team > Rebase > Skip Rebase' auf Projektebene wählen. Dies wird von EGit mit 'Rebase finished successfully' und einer 1 Up Arrow Dekoration quittiert. Nun muss man nur noch 'Push to Upstream' wählen.
User B kann nun pullen und sieht dann die Änderungen von User A.
'Team > Synchronize Workspace' auf irgendeinem Projekt im Package Explorer wählen. Es wird der ganze Workspace mit dem Server-Repository-Stand verglichen. Hier sieht man nicht nur die eigenen Änderungen, sondern auch die von anderen Usern zwischenzeitlich gepushten Commits. Von anderen Usern noch nicht gepushte Commits sind hier noch unsichtbar. Wenn man nur die eigenen Änderungen sehen möchte, stellt man die Synchronize View auf 'Outgoing Mode' ein. Eingehende Änderungen kann man mit dem Pull Button laden.
Über das Dropdownmenü kann man das Model auf 'Git Commits' einstellen. Die Dateiänderungen werden dann nach Commits gruppiert. So kann man gut erkennen, welche Commits noch zu pushen sind. Denn die Hochpfeil-Dekoration zeigt ja nur die Anzahl der zu pushenden Commits an.
In der Praxis arbeitet man wohl meist mit Featurebranches. Wenn man alleine ein Feature bearbeitet, dann spielt das Mergen oder Merge Konflikte keine Rolle. Mergen muss dann erst der Integrator - und der Integrator wird meist sehr fit in Git sein.
In den Window > Preferences sollte man das Git Timeout von 30 auf 60 Sekunden hochsetzen, damit es z.B. beim Pushen nicht zu einem "Write Timeout..." kommt. Wenn alle in einem LAN arbeiten, wird diese Einstellung wohl nicht nötig sein.