3 Unverzügliches 'Branchen' und 'Mergen' sind die hervorstechenden
6 *Problem*: Externe Faktoren zwingen zum Wechsel des Kontext. Ein schwerwiegender Fehler in der veröffentlichten Version tritt ohne Vorwarnung auf. Die Frist für ein bestimmtes Leistungsmerkmal rückt näher. Ein Entwickler, dessen Unterstützung für eine Schlüsselstelle im Projekt wichtig ist, verlässt das Team. In allen Fällen musst du alles stehen und liegen lassen und dich auf eine komplett andere Aufgabe konzentrieren.
8 Den Gedankengang zu unterbrechen ist schlecht für die Produktivität und je
9 komplizierter der Kontextwechsel ist, desto größer ist der Verlust. Mit
10 zentraler Versionsverwaltung müssen wir eine neue Arbeitskopie vom Server
11 herunterladen. Bei verteilen Systemen ist das viel besser, da wir die
12 benötigt Version lokal 'clonen' können.
14 Doch das 'Clonen' bringt das Kopieren des gesamten Arbeitsverzeichnis wie
15 auch die ganze Geschichte bis zum angegebenen Punkt mit sich. Auch wenn Git
16 die Kosten durch Dateifreigaben und Verknüpfungen reduziert, müssen doch die
17 gesamten Projektdateien im neuen Arbeitsverzeichnis erstellt werden.
19 *Lösung*: Git hat ein besseres Werkzeug für diese Situationen, die wesentlich schneller und platzsparender als 'clonen' ist: *git branch*.
21 Mit diesem Zauberwort verwandeln sich die Dateien in deinem
22 Arbeitsverzeichnis plötzlich von einer Version in eine andere. Diese
23 Verwandlung kann mehr als nur in der Geschichte vor und zurück gehen. Deine
24 Dateien können sich verwandeln, vom aktuellsten Stand, zur experimentellen
25 Version, zum neusten Entwicklungsstand, zur Version deines Freundes und so
28 === Die Chef-Taste ===
30 Hast du schon einmal ein Spiel gespielt, wo beim Drücken einer Taste (``der
31 Chef-Taste''), der Monitor sofort ein Tabellenblatt oder etwas anderes
32 angezeigt hat? Dass, wenn der Chef ins Büro spaziert, während du das Spiel
33 spielst, du es schnell verstecken kannst?
35 In irgendeinem Verzeichnis:
37 $ echo "Ich bin klüger als mein Chef" > meinedatei.txt
40 $ git commit -m "Erster Stand"
42 Wir haben ein Git 'Repository' erstellt, das eine Textdatei mit einer
43 bestimmten Nachricht enthält. Nun gib ein:
45 $ git checkout -b chef # scheinbar hat sich danach nichts geändert
46 $ echo "Mein Chef ist klüger als ich" > meinedatei.txt
47 $ git commit -a -m "Ein anderer Stand"
49 Es sieht aus als hätten wir unsere Datei überschrieben und 'commitet'. Aber
50 es ist eine Illusion. Tippe:
52 $ git checkout master # wechsle zur Originalversion der Datei
54 und Simsalabim! Die Textdatei ist wiederhergestellt. Und wenn der Chef in
55 diesem Verzeichnis herumschnüffelt, tippe:
57 $ git checkout chef # wechsle zur Version die der Chef ruhig sehen kann
59 Du kannst zwischen den beiden Versionen wechseln, so oft du willst und du
60 kannst unabhängig voneinander in jeder Version Änderungen 'commiten'
64 [[branch]] Sagen wir, du arbeitest an einer Funktion und du musst, warum
65 auch immer, drei Versionen zurückgehen um ein paar print Anweisungen
66 einzufügen, damit du siehst, wie etwas funktioniert. Dann:
71 Nun kannst du überall wild temporären Code hinzufügen. Du kannst diese
72 Änderungen sogar 'commiten'. Wenn du fertig bist,
76 um zur ursprünglichen Arbeit zurückzukehren. Beachte, dass alle Änderungen,
77 die nicht 'commitet' sind übernommen werden.
79 Was, wenn du am Ende die temporären Änderungen sichern willst? Einfach:
81 $ git checkout -b schmutzig
83 und 'commite' bevor du auf den 'Master Branch' zurückschaltest. Wann immer
84 du zu deiner Schmutzarbeit zurückkehren willst, tippe einfach:
86 $ git checkout schnmutzig
88 Wir sind mit dieser Anweisung schon in einem früheren Kapitel in Berührung
89 gekommen, als wir das Laden alter Stände besprochen haben. Nun können wir
90 die ganze Geschichte erzählen: Die Dateien ändern sich zu dem angeforderten
91 Stand, aber wir müssen den 'Master Branch' verlassen. Jeder 'Commit' ab
92 jetzt führt deine Dateien auf einen anderen Weg, dem wir später noch einen
95 Mit anderen Worten, nach dem Abrufen eines alten Stands versetzt dich Git
96 automatisch in einen neuen, unbenannten 'Branch', der mit *git checkout -b*
97 benannt und gesichert werden kann.
99 === Schnelle Fehlerbehebung ===
101 Du steckst mitten in der Arbeit, als es heißt alles fallen zu lassen um
102 einen neu entdeckten Fehler in 'Commit' `1b6d...` zu beheben:
105 $ git checkout -b fixes 1b6d
107 Dann, wenn du den Fehler behoben hast:
109 $ git commit -a -m "Fehler behoben"
110 $ git checkout master
112 und fahre mit deiner ursprünglichen Arbeit fort. Du kannst sogar die frisch
113 gebackene Fehlerkorrektur auf Deinen aktuellen Stand übernehmen:
119 Mit einigen Versionsverwaltungssystemen ist das Erstellen eines 'Branch'
120 einfach, aber das Zusammenfügen ('Mergen') ist schwierig. Mit Git ist
121 'Mergen' so einfach, dass du gar nicht merkst, wenn es passiert.
123 Tatsächlich sind wir dem 'Mergen' schon lange begegnet. Die *pull* Anweisung
124 holt ('fetch') eigentlich die 'Commits' und verschmilzt ('merged') diese
125 dann mit dem aktuellen 'Branch'. Wenn du keine lokalen Änderungen hast, dann
126 ist 'merge' eine 'schnelle Weiterleitung', ein Ausnahmefall, ähnlich dem
127 Abrufen der letzten Version eines zentralen Versionsverwaltungssystems. Wenn
128 du aber Änderungen hast, wird Git diese automatisch 'mergen' und dir
131 Normalerweise hat ein 'Commit' genau einen Eltern-'Commit', nämlich den
132 vorhergehenden 'Commit'. Das 'Mergen' mehrerer 'Branches' erzeugt einen
133 'Commit' mit mindestens zwei Eltern. Das wirft die Frage auf: Welchen
134 'Commit' referenziert `HEAD~10` tatsächlich? Ein 'Commit' kann mehrere
135 Eltern haben, welchem folgen wir also?
137 Es stellt sich heraus, dass diese Notation immer den ersten Elternteil
138 wählt. Dies ist erstrebenswert, denn der aktuelle 'Branch' wird zum ersten
139 Elternteil während eines 'Merge'; häufig bist du nur von Änderungen
140 betroffen, die du im aktuellen 'Branch' gemacht hast, als von den Änderungen
141 die von anderen 'Branches' eingebracht wurden.
143 Du kannst einen bestimmten Elternteil mit einem Caret-Zeichen
144 referenzieren. Um zum Beispiel die Logs vom zweiten Elternteil anzuzeigen:
148 Du kannst die Nummer für den ersten Elternteil weglassen. Um zum Beispiel
149 die Unterschiede zum ersten Elternteil anzuzeigen:
153 Du kannst diese Notation mit anderen Typen kombinieren. Zum Beispiel:
155 $ git checkout 1b6d^^2~10 -b uralt
157 beginnt einen neuen 'Branch' ``uralt'', welcher den Stand 10 'Commits'
158 zurück vom zweiten Elternteil des ersten Elternteil des 'Commits', dessen
159 Hashwert mit 1b6d beginnt.
161 === Kontinuierlicher Arbeitsfluss ===
163 In Herstellungsprozessen muss der zweiter Schritt eines Plans oft auf die
164 Fertigstellung des ersten Schritt warten. Ein Auto, das repariert werden
165 soll, steht unbenutzt in der Garage bis ein Ersatzteil geliefert wird. Ein
166 Prototyp muss warten, bis ein Baustein fabriziert wurde, bevor die
167 Konstruktion fortgesetzt werden kann.
169 Bei Softwareprojekten kann das ähnlich sein. Der zweite Teil eines
170 Leistungsmerkmals muss warten, bis der erste Teil veröffentlicht und
171 getestet wurde. Einige Projekte erfordern, dass dein Code überprüft werden
172 muss bevor er akzeptiert wird, du musst also warten, bis der erste Teil
173 geprüft wurde, bevor du mit dem zweiten Teil anfangen kannst.
175 Dank des schmerzlosen 'Branchen' und 'Mergen' können wir die Regeln beugen
176 und am Teil II arbeiten, bevor Teil I offiziell freigegeben
177 wurde. Angenommen du hast Teil I 'commitet' und zur Prüfung
178 eingereicht. Sagen wir du bist im `master` 'Branch'. Dann 'branche' zu Teil
181 $ git checkout -b teil2
183 Du arbeitest also an Teil II und 'commitest' deine Änderungen
184 regelmäßig. Irren ist menschlich und so kann es vorkommen, dass du zurück zu
185 Teil I willst um einen Fehler zu beheben. Wenn du Glück hast oder sehr gut
186 bist, kannst du die nächsten Zeilen überspringen.
188 $ git checkout master # Gehe zurück zu Teil I.
190 $ git commit -a # 'Commite' die Lösung.
191 $ git checkout teil2 # Gehe zurück zu Teil II.
192 $ git merge master # 'Merge' die Lösung.
194 Schließlich, Teil I ist zugelassen:
196 $ git checkout master # Gehe zurück zu Teil I.
197 $ submit files # Veröffentliche deine Dateien!
198 $ git merge teil2 # 'Merge' in Teil II.
199 $ git branch -d teil2 # Lösche den Branch "teil2"
201 Nun bist du wieder im `master` 'Branch', mit Teil II im Arbeitsverzeichnis.
203 Es ist einfach, diesen Trick auf eine beliebige Anzahl von Teilen zu
204 erweitern. Es ist genauso einfach rückwirkend zu 'branchen': angenommen, du
205 merkst zu spät, dass vor sieben 'Commits' ein 'Branch' erforderlich gewesen
208 $ git branch -m master teil2 # Umbenennen des 'Branch' "master" zu "teil2".
209 $ git branch master HEAD~7 # Erstelle neuen "master", 7 Commits voraus
211 Der `master` Branch enthält nun Teil I, und der `teil2` Branch enthält den
212 Rest. Wir befinden uns in letzterem Branch; wir haben `master` erzeugt ohne
213 dorthin zu wechseln, denn wir wollen im `teil2` weiterarbeiten. Das ist
214 unüblich. Bisher haben wir unmittelbar nach dem Erstellen in einen 'Branch'
217 $ git checkout HEAD~7 -b master # erzeuge einen Branch, und wechsle zu ihm.
219 === Mischmasch Reorganisieren ===
221 Vielleicht magst du es, alle Aspekte eines Projekts im selben 'Branch'
222 abzuarbeiten. Du willst deine laufenden Arbeiten für dich behalten und
223 andere sollen deine 'Commits' nur sehen, wenn du sie hübsch organisiert
224 hast. Beginne ein paar 'Branches':
226 $ git branch sauber # Erzeuge einen Branch für gesäuberte Commits.
227 $ git checkout -b mischmasch # Erzeuge und wechsle in den Branch zum Arbeiten.
229 Fahre fort alles zu bearbeiten: Behebe Fehler, füge Funktionen hinzu,
230 erstelle temporären Code und so weiter und 'commite' deine Änderungen
233 $ git checkout bereinigt
234 $ git cherry-pick mischmasch^^
236 wendet den Urahn des obersten 'Commit' des ``mischmasch'' 'Branch' auf den
237 ``bereinigt'' 'Branch' an. Durch das Herauspicken der Rosinen kannst du
238 einen 'Branch' konstruieren, der nur endgültigen Code enthält und
239 zusammengehörige 'Commits' gruppiert hat.
241 === 'Branches' verwalten ===
243 Ein Liste aller 'Branches' bekommst du mit:
247 Standardmäßig beginnst du in einem 'Branch' namens ``master''. Einige
248 plädieren dafür, den ``master'' 'Branch' unangetastet zu lassen und für
249 seine Arbeit einen neuen 'Branch' anzulegen.
251 Die *-d* und *-m* Optionen erlauben dir 'Branches' zu löschen und zu
252 verschieben (umzubenennen). Siehe *git help branch*.
254 Der ``master'' 'Branch' ist ein nützlicher Brauch. Andere können davon
255 ausgehen, dass dein 'Repository' einen 'Branch' mit diesem Namen hat und
256 dass er die offizielle Version enthält. Auch wenn du den ``master'' 'Branch'
257 umbenennen oder auslöschen könntest, kannst du diese Konvention aber auch
260 === Temporäre 'Branches' ===
262 Nach einer Weile wirst du feststellen, dass du regelmäßig kurzlebige
263 'Branches' erzeugst, meist aus dem gleichen Grund: jeder neue 'Branch' dient
264 lediglich dazu, den aktuellen Stand zu sichern, damit du kurz zu einem alten
265 Stand zurück kannst um eine vorrangige Fehlerbehebung zu machen oder
268 Es ist vergleichbar mit dem kurzzeitigen Umschalten des Fernsehkanals um zu
269 sehen was auf dem anderen Kanal los ist. Doch anstelle ein paar Knöpfe zu
270 drücken, machst du 'create', 'check out', 'merge' und 'delete' von
271 temporären 'Branches'. Glücklicherweise hat Git eine Abkürzung dafür, die
272 genauso komfortabel ist wie eine Fernbedienung:
276 Das sichert den aktuellen Stand an einem temporären Ort ('stash'=Versteck)
277 und stellt den vorherigen Stand wieder her. Dein Arbeitsverzeichnis
278 erscheint wieder exakt in dem Zustand wie es war, bevor du anfingst zu
279 editieren. Nun kannst du Fehler beheben, Änderungen vom zentralen
280 'Repository' holen ('pull') und so weiter. Wenn du wieder zurück zu deinen
281 Änderungen willst, tippe:
283 $ git stash apply # Es kann sein, dass du Konflikte auflösen musst.
285 Du kannst mehrere 'stashes' haben und diese unterschiedlich handhaben. Siehe
286 *git help stash*. Wie du dir vielleicht schon gedacht hast, verwendet Git
287 'Branches' im Hintergrund um diesen Zaubertrick durchzuführen.
289 === Arbeite wie du willst ===
291 Du magst dich fragen, ob 'Branches' diesen Aufwand Wert sind. Immerhin sind
292 'Clone' fast genauso schnell und du kannst mit *cd* anstelle von
293 esoterischen Git Befehlen zwischen ihnen wechseln.
295 Betrachten wir Webbrowser. Warum mehrere Tabs unterstützen und mehrere
296 Fenster? Weil beides zu erlauben eine Vielzahl an Stilen unterstützt. Einige
297 Anwender möchten nur ein Browserfenster geöffnet haben und benutzen Tabs für
298 unterschiedliche Webseiten. Andere bestehen auf dem anderen Extrem: mehrere
299 Fenster, ganz ohne Tabs. Wieder andere bevorzugen irgendetwas dazwischen.
301 'Branchen' ist wie Tabs für dein Arbeitsverzeichnis und 'Clonen' ist wie das
302 Öffnen eines neuen Browserfenster. Diese Operationen sind schnell und lokal,
303 also warum nicht damit experimentieren um die beste Kombination für sich
304 selbst zu finden? Git lässt dich genauso arbeiten, wie du es willst.