Added two mirrors.
[gitmagic.git] / de / history.txt
blob6b9c8a64c09b741562a163ea5466d26de7b3db44
1 == Geschichtsstunde ==
3 Eine Folge von Git's verteilter Natur ist, dass die Chronik einfach
4 verändert werden kann. Aber, wenn du an der Vergangenheit manipulierst, sei
5 vorsichtig: verändere nur den Teil der Chronik, den du ganz alleine hast. So
6 wie Nationen ewig diskutieren, wer welche Greueltaten vollbracht hat, wirst
7 du beim Abgleichen in Schwierigkeiten geraten, falls jemand einen 'Clone'
8 mit abweichender Chronik hat und die Zweige sich austauschen sollen.
10 Einige Entwickler setzen sich nachhaltig für die Unantastbarkeit der Chronik
11 ein, mit allen Fehlern, Nachteilen und Mängeln. Andere denken, daß Zweige
12 vorzeigbar gemacht werden sollten, bevor sie auf die Öffentlichkeit
13 losgelassen werden. Git versteht beide Gesichtspunkte. Wie 'Clonen',
14 'Branchen' und 'Mergen' ist das Umschreiben der Chronik lediglich eine
15 weitere Stärke, die Git dir bietet. Es liegt an dir diese weise zu nutzen.
17 === Ich nehme alles zurück ===
19 Hast du gerade 'commitet', aber du hättest gerne eine andere Beschreibung
20 eingegeben? Dann gib ein:
22  $ git commit --amend
24 um die letzte Beschreibung zu ändern. Du merkst, dass du vergessen hast eine
25 Datei hinzuzufügen? Führe *git add* aus um sie hinzuzufügen und dann die
26 vorhergehende Anweisung.
28 Du willst noch ein paar Änderungen zu deinem letzten 'Commit' hinzufügen?
29 Dann mache diese Änderungen und gib ein:
31  $ git commit --amend -a
33 === ... und noch viel mehr ===
35 Nehmen wir jetzt an, das vorherige Problem ist zehnmal schlimmer. Nach einer
36 längeren Sitzung hast du einen Haufen 'Commits' gemacht. Aber du bist mit
37 der Art der Organisation nicht glücklich und einige 'Commits' könnten etwas
38 umformuliert werden. Dann gib ein:
40  $ git rebase -i HEAD~10
42 und die letzten zehn 'Commits' erscheinen in deinem bevorzugten
43 $EDITOR. Auszug aus einem Beispiel:
45     pick 5c6eb73 Link repo.or.cz hinzugefügt
46     pick a311a64 Analogien in "Arbeite wie du willst" umorganisiert
47     pick 100834f Push-Ziel zum Makefile hinzugefügt
49 Dann:
51 - Entferne 'Commits' durch das Löschen von Zeilen.
52 - Organisiere 'Commits' durch verschieben von Zeilen.
53 - Ersetze `pick` mit:
54    * `edit` um einen 'Commit' für 'amends' zu markieren.
55    * `reword` um die Log-Beschreibung zu ändern.
56    * `squash` um einen 'Commit' mit dem vorhergehenden zu vereinen ('merge').
57    * `fixup` um einen 'Commit' mit dem vorhergehenden zu vereinen ('merge') und die Log-Beschreibung zu verwerfen.
59 Speichere und Beende. Wenn du einen 'Commit' mit 'edit' markiert hast, gib
60 ein:
62  $ git commit --amend
64 Ansonsten:
66  $ git rebase --continue
68 Also 'commite' früh und oft: du kannst später mit 'rebase' aufräumen.
70 === Lokale Änderungen zum Schluß ===
72 Du arbeitest an einem aktiven Projekt. Über die Zeit haben sich einige
73 lokale 'Commits' angesammelt und dann synchronisierst du mit einem 'Merge'
74 mit dem offiziellen Zweig. Dieser Zyklus wiederholt sich ein paar Mal bevor
75 du zum 'Pushen' in den zentralen Zweig bereit bist.
77 Aber nun ist die Chronik in deinem lokalen Git-'Clone' ein chaotisches
78 Durcheinander deiner Änderungen und den Änderungen vom offiziellen Zweig. Du
79 willst alle Deine Änderungen lieber in einem fortlaufenden Abschnitt und
80 hinter den offiziellen Änderungen sehen.
82 Das ist eine Aufgabe für *git rebase*, wie oben beschrieben. In vielen
83 Fällen kannst du den *--onto* Schalter benutzen um Interaktion zu vermeiden.
85 Siehe auch *git help rebase* für ausführliche Beispiele dieser erstaunlichen
86 Anweisung. Du kannst auch 'Commits' aufteilen. Du kannst sogar 'Branches' in
87 einem 'Repository' umorganisieren.
89 === Chronik umschreiben ===
91 Gelegentlich brauchst du Versionsverwaltung vergleichbar dem Wegretuschieren
92 von Personen aus einem offiziellen Foto, um diese in stalinistischer Art aus
93 der Geschichte zu löschen. Stell dir zum Beispiel vor, du willst ein Projekt
94 veröffentlichen, aber es enthält eine Datei, die aus irgendwelchen Gründen
95 privat bleiben muss. Vielleicht habe ich meine Kreditkartennummer in einer
96 Textdatei notiert und diese versehentlich dem Projekt hinzugefügt. Die Datei
97 zu löschen ist zwecklos, da über ältere 'Commits' auf sie zugegriffen werden
98 könnte. Wir müssen die Datei aus allen 'Commits' entfernen:
100  $ git filter-branch --tree-filter 'rm sehr/geheime/Datei' HEAD
102 Siehe *git help filter-branch*, wo dieses Beispiel erklärt und eine
103 schnellere Methode vorstellt wird. Allgemein, *filter-branch* lässt dich
104 große Bereiche der Chronik mit einer einzigen Anweisung verändern.
106 Danach beschreibt der Ordner +.git/refs/original+ den Zustand der Lage vor
107 der Operation. Prüfe, ob die 'filter-branch' Anweisung getan hat was du
108 wolltest, dann lösche dieses Verzeichnis bevor du weitere 'filter-branch'
109 Operationen durchführst.
111 Zuletzt, ersetze alle 'Clones' deines Projekts mit deiner überarbeiteten
112 Version, falls du später mit ihnen interagieren möchtest.
114 === Geschichte machen ===
116 [[makinghistory]] Du möchtest ein Projekt zu Git umziehen? Wenn es mit einem
117 der bekannteren Systeme verwaltet wird, besteht die Möglichkeit, dass schon
118 jemand ein Skript geschrieben hat, das die gesamte Chronik für Git
119 exportiert.
121 Anderenfalls, sieh dir *git fast-import* an, das Text in einem speziellen
122 Format einliest um eine Git Chronik von Anfang an zu
123 erstellen. Normalerweise wird ein Skript, das diese Anweisung benutzt,
124 hastig zusammengeschustert und einmalig ausgeführt um das Projekt in einem
125 einzigen Lauf zu migrieren.
127 Erstelle zum Beispiel aus folgendem Listing eine temporäre Datei, z.B. `/tmp/history`:
128 ----------------------------------
129 commit refs/heads/master committer Alice <alice@example.com> Thu, 01 Jan
130 1970 00:00:00 +0000 data <<EOT Initial commit.  EOT
132 M 100644 inline hello.c data <<EOT #include <stdio.h>
134 int main() {
135   printf("Hallo, Welt!\n");
136   return 0;
141 commit refs/heads/master committer Bob <bob@example.com> Tue, 14 Mar 2000
142 01:59:26 -0800 data <<EOT Ersetze printf() mit write().  EOT
144 M 100644 inline hello.c data <<EOT #include <unistd.h>
146 int main() {
147   write(1, "Hallo, Welt!\n", 14);
148   return 0;
152 ----------------------------------
154 Dann, erstelle ein Git 'Repository' aus dieser temporären Datei, durch
155 Eingabe von:
157  $ mkdir project; cd project; git init
158  $ git fast-import --date-format=rfc2822 < /tmp/history
160 Die aktuellste Version des Projekts kannst du abrufen ('checkout') mit:
162  $ git checkout master .
164 Die Anweisung *git fast-export* konvertiert jedes 'Repository' in das *git
165 fast-import* Format, diese Ausgabe kannst du studieren um Exporteure zu
166 schreiben und außerdem um 'Repositories' in Klartext zu übertragen.
167 untersuchen wes you can study for writing exporters, and also to transport
168 repositories in a human-readable format. Wirklich, diese Anweisung kann
169 Klartext-'Repositories' über reine Textkanäle übertragen.
171 === Wo ging alles schief? ===
173 Du hast gerade ein Funktion in deiner Anwendung entdeckt, die nicht mehr
174 funktioniert und du weißt sicher, dass sie vor ein paar Monaten noch
175 ging. Argh! Wo kommt dieser Fehler her? Hättest du nur die Funktion während
176 der Entwicklung getestet.
178 Dafür ist es nun zu spät. Wie auch immer, vorausgesetzt du hast oft
179 'comittet', kann Git dir sagen, wo das Problem liegt:
181  $ git bisect start
182  $ git bisect bad HEAD
183  $ git bisect good 1b6d
185 Git ruft eine Stand ab, der genau dazwischen liegt. Teste die Funktion und
186 wenn sich immer noch nicht funktioniert:
188  $ git bisect bad
190 Wenn nicht, ersetzte "bad" mit "good". Git versetzt dich wieder auf einen
191 Stand genau zwischen den bekannten Versionen "good" und "bad" und reduziert
192 so die Möglichkeiten. Nach ein paar Durchläufen wird dich diese binäre Suche
193 zu dem 'Commit' führen, der die Probleme verursacht. Wenn du deine
194 Ermittlungen abgeschlossen hast, kehre zum Originalstand zurück mit:
196  $ git bisect reset
198 Anstatt jede Änderung per Hand zu untersuchen, automatisiere die Suche durch
199 Ausführen von:
201  $ git bisect run mein_skript
203 Git benutzt den Rückgabewert der übergebenen Anweisung, normalerweise ein
204 Skript für einmalige Ausführung, um zu entscheiden, ob eine Änderung gut
205 ('good') oder schlecht ('bad') ist: Das Skript sollte 0 für 'good'
206 zurückgeben, 125 wenn die Änderung übersprungen werden soll und irgendetwas
207 zwischen 1 und 127 für 'bad'. Ein negativer Rückgabewert beendet die
208 'bisect'-Operation sofort.
210 Du kannst noch viel mehr machen: die Hilfe erklärt, wie man
211 'bisect'-Operationen visualisiert, das 'bisect'-Log untersucht oder
212 wiedergibt und sicher unschuldige Änderungen ausschließt um die Suche zu
213 beschleunigen.
215 === Wer ist verantwortlich? ===
217 Wie viele andere Versionsverwaltungssysteme hat Git eine 'blame' Anweisung:
219  $ git blame bug.c
221 das jede Zeile in der angegebenen Datei kommentiert um anzuzeigen, wer sie
222 zuletzt geändert hat und wann. Im Gegensatz zu vielen anderen
223 Versionsverwaltungssystemen funktioniert diese Operation offline, es wird
224 nur von der lokalen Festplatte gelesen.
226 === Persönliche Erfahrungen ===
228 In einem zentralisierten Versionsverwaltungssystem ist das Bearbeiten der
229 Chronik eine schwierige Angelegenheit und den Administratoren
230 vorbehalten. 'Clonen', 'Branchen' und 'Mergen' sind unmöglich ohne
231 Netzwerkverbindung. Ebenso grundlegende Funktionen wie das Durchsuchen der
232 Chronik oder das 'comitten' einer Änderung. In manchen Systemen benötigt der
233 Anwender schon eine Netzwerkverbindung nur um seine eigenen Änderungen zu
234 sehen oder um eine Datei zum Bearbeiten zu öffnen.
236 Zentralisierte Systeme schließen es aus offline zu arbeiten und benötigen
237 teurere Netzwerkinfrastruktur, vor allem, wenn die Zahl der Entwickler
238 steigt. Am wichtigsten ist, dass alle Operationen bis zu einem gewissen Grad
239 langsamer sind, in der Regel bis zu dem Punkt, wo Anwender erweiterte
240 Anweisungen scheuen, bis sie absolut notwendig sind. In extremen Fällen
241 trifft das auch auf die grundlegenden Anweisungen zu. Wenn Anwender langsame
242 Anweisungen ausführen müssen, sinkt die Produktivität, da der Arbeitsfluss
243 unterbrochen wird.
245 Ich habe diese Phänomen aus erster Hand erfahren. Git war das erste
246 Versionsverwaltungssystem, das ich benutzt habe. Ich bin schnell in die
247 Anwendung hineingewachsen und betrachtete viele Funktionen als
248 selbstverständlich. Ich habe einfach vorausgesetzt, dass andere Systeme
249 ähnlich sind: die Auswahl eines Versionsverwaltungssystems sollte nicht
250 anders sein als die Auswahl eines Texteditors oder Internetbrowser.
252 Ich war geschockt, als ich später gezwungen war ein zentralisiertes System
253 zu benutzen. Eine unzuverlässige Internetverbindung stört mit Git nicht
254 sehr, aber sie macht die Entwicklung unerträglich, wenn sie so zuverlässig
255 wie ein lokale Festplatte sein sollte. Zusätzlich habe ich mich dabei
256 ertappt, bestimmte Anweisungen zu vermeiden, um die damit verbundenen
257 Wartezeiten zu vermeiden und das hat mich letztendlich davon abgehalten
258 meinem gewohnten Arbeitsablauf zu folgen.
260 Wenn ich eine langsame Anweisung auszuführen hatte, wurde durch die
261 Unterbrechung meiner Gedankengänge dem Arbeitsfluss ein unverhältnismäßiger
262 Schaden zugefügt. Während dem Warten auf das Ende der Serverkommunikation
263 tat ich etwas anderes um die Wartezeit zu überbrücken, zum Beispiel E-Mails
264 lesen oder Dokumentation schreiben. Wenn ich zur ursprünglichen Arbeit
265 zurückkehrte, war die Operation längst beendet und ich vergeudete noch mehr
266 Zeit beim Versuch mich zu erinnern was ich getan habe. Menschen sind nicht
267 gut im Kontextwechsel.
269 Da war auch ein interessanter
270 http://de.wikipedia.org/wiki/Tragik_der_Allmende[Tragik-der-Allmende]
271 Effekt: Netzwerküberlastungen erahnend, verbrauchten einzelne Individuen für
272 diverse Operationen mehr Netzwerkbandbreite als erforderlich, um zukünftige
273 Engpässe zu vermeiden. Die Summe der Bemühungen verschlimmerte die
274 Überlastungen, was einzelne wiederum ermutigte noch mehr Bandbreite zu
275 verbrauchen um noch längere Wartezeiten zu verhindern.