Git Blog

Git im Team

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:

Merge Fall 1: User A und B ändern unterschiedliche Dateien

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.

Merge Fall 2: User A und B ändern unterschiedliche Methoden in der gleichen Datei

Git ist schlau. Dieser Fall verhält sich wie Fall 1.

Merge Fall 3: User A und B ändern die gleiche Zeile der gleichen Datei mit unterschiedlichem Inhalt

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.

Troubleshooting

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.

Rebase

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.

Vor dem Committen: Sehen was man selbst geändert hat /
Vor dem Pushen: Sehen was man committet hat

'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.

Taggen

  1. Git Repositories Perspective im Eclipse anwählen
  2. Den lokalen Branch, den man taggen möchte, mittels Doppelklick auschecken
  3. Unter <Repositoryname>\Tags Rechtsklick > "Create Tag" anwählen
  4. Tag name (z.B. "release-2-56-14-8") und Commit message (z.B. "Auslieferung 2.56.14.8") eingeben
    Der tag ist dann erstellt, aber nur lokal !
  5. Rechtsklick auf den neuen tag: Push Tag...
  6. Next
  7. Target ref name: refs/tags/<tagname>
  8. Finish

Branch auf Server löschen

  1. Im Package Explorer von Eclipse: Team > Remote > Push
  2. Normalerweise kann man direkt "Next" anklicken.
  3. Feld "Remote ref to delete": refs/heads/branchname
  4. "Add spec" Button
  5. Finish Button.
  6. Es wird eine delete Bestätigung ausgegeben.

Anmerkungen

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.