|
| 1 | +== Anhang A: Git's Mängel == |
| 2 | + |
| 3 | +Ein paar Git-Probleme habe ich bisher unter den Teppich gekehrt. Einige |
| 4 | +lassen sich einfach mit Skripten und 'Hooks' lösen, andere erfordern eine |
| 5 | +Reorganisation oder Neudefinition des gesamten Projekt und für die wenigen |
| 6 | +verbleibenden Beeinträchtigungen kannst Du nur auf eine Lösung warten. Oder |
| 7 | +noch besser, anpacken und mithelfen. |
| 8 | + |
| 9 | +=== SHA1 Schwäche === |
| 10 | + |
| 11 | +Mit der Zeit entdecken Kryptographen immer mehr Schwächen an SHA1. Schon |
| 12 | +heute wäre es technisch machbar für finanzkräftige Unternehmen |
| 13 | +Hash-Kollisionen zu finden. In ein paar Jahren hat vielleicht schon ein ganz |
| 14 | +normaler Heim-PC ausreichend Rechenleistung um ein Git 'Reopsitory' |
| 15 | +unbemerkt zu korrumpieren. |
| 16 | + |
| 17 | +Hoffentlich stellt Git auf eine bessere Hash Funktion um, bevor die |
| 18 | +Forschung SHA1 komplett unnütz macht. |
| 19 | + |
| 20 | +=== Microsoft Windows === |
| 21 | + |
| 22 | +Git unter Microsoft Windows kann frustrierend sein: |
| 23 | + |
| 24 | +- http://cygwin.com/[Cygwin], eine Linux ähnliche Umgebung für Windows, |
| 25 | +enthält http://cygwin.com/packages/git/[eine Windows Portierung von Git]. |
| 26 | + |
| 27 | +- http://code.google.com/p/msysgit/[Git unter MSys] ist eine Alternative, |
| 28 | +die sehr wenig Laufzeitunterstützung erfordert, jedoch bedürfen einige |
| 29 | +Kommandos noch einer Überarbeitung. |
| 30 | + |
| 31 | +=== Dateien ohne Bezug === |
| 32 | + |
| 33 | +Wenn Dein Projekt sehr groß ist und viele Dateien enthält, die in keinem |
| 34 | +direkten Bezug stehen, trotzdem aber häufig geändert werden, kann Git |
| 35 | +nachteiliger sein als andere Systeme, weil es keine einzelnen Dateien |
| 36 | +überwacht. Git überwacht immer das ganze Projekt, was normalerweise schon |
| 37 | +von Vorteil ist. |
| 38 | + |
| 39 | +Eine Lösung ist es, Dein Projekt in kleinere Stücke auszuteilen, von denen |
| 40 | +jedes nur die in Beziehung stehenden Dateien enthält. Benutze *git |
| 41 | +submodule* wenn Du trotzdem alles in einem einzigen 'Repository' halten |
| 42 | +willst. |
| 43 | + |
| 44 | +=== Wer macht was? === |
| 45 | + |
| 46 | +Einige Versionsverwaltungssysteme zwingen Dich explizit eine Datei auf |
| 47 | +irgendeine Weise für die Bearbeitung zu kennzeichnen. Auch wenn es extrem |
| 48 | +Lästig, wenn es die Kommunikation mit einem zentralen Server erfordert, so |
| 49 | +hat es doch zwei Vorteile: |
| 50 | + |
| 51 | + 1. Unterschiede sind schnell gefunden, weil nur die markierten Dateien |
| 52 | + untersucht werden müssen. |
| 53 | + |
| 54 | + 2. Jeder kann herausfinden wer sonst gerade an einer Datei arbeitet, indem |
| 55 | + er beim zentralen Server anfragt, wer die Datei zum Bearbeiten markiert |
| 56 | + hat. |
| 57 | + |
| 58 | +Mit geeigneten Skripten kannst Du das auch mit Git hinkriegen. Das erfordert |
| 59 | +aber die Mitarbeit der Programmierer, denn sie müssen die Skripte auch |
| 60 | +aufrufen, wenn sie eine Datei bearbeiten. |
| 61 | + |
| 62 | +=== Dateihistorie === |
| 63 | + |
| 64 | +Da Git die Änderungen über das gesamte Projekt aufzeichnet, erfordert die |
| 65 | +Rekonstruktion des Verlaufs einer einzelnen Datei mehr Aufwand als in |
| 66 | +Versionsverwaltungssystemen die einzelne Dateien überwachen. |
| 67 | + |
| 68 | +Die Nachteile sind üblicherweise gering und werden gern in Kauf genommen, da |
| 69 | +andere Operationen dafür unglaublich effizient sind. Zum Beispiel ist `git |
| 70 | +checkout` schneller als `cp -a` und projektweite Unterschiede sind besser zu |
| 71 | +komprimieren als eine Sammlung von Änderungen auf Dateibasis. |
| 72 | + |
| 73 | +=== Der erster Klon === |
| 74 | + |
| 75 | +Einen Klon zu erstellen ist aufwendiger als in anderen |
| 76 | +Versionsverwaltungssystemen, wenn ein längerer Verlauf existiert. |
| 77 | + |
| 78 | +Der initiale Aufwand lohnt sich aber auf längere Sicht, da die meisten |
| 79 | +zukünftigen Operationen dann schnell und offline erfolgen. Trotzdem gibt es |
| 80 | +Situationen, in denen es besser ist einen oberflächlichen Klon mit der |
| 81 | +`--depth` Option zu erstellen. Das geht wesentlich schneller, aber der |
| 82 | +resultierende Klon hat nur eingeschränkte Funktionalität. |
| 83 | + |
| 84 | +=== Unbeständige Projekte === |
| 85 | + |
| 86 | +Git wurde geschrieben um schnell zu sein, im Hinblick auf die Größe der |
| 87 | +Änderungen. Leute machen kleine Änderungen von Version zu Version. Ein |
| 88 | +einzeiliger Bugfix hier, eine neue Funktion da, verbesserte Kommentare und |
| 89 | +so weiter. Aber wenn sich Deine Dateien zwischen aufeinander folgenden |
| 90 | +Versionen gravierend ändern, dann wird zwangsläufig mit jedem 'Commit' Dein |
| 91 | +Verlauf um die Größe des gesamten Projekts wachsen. |
| 92 | + |
| 93 | +Es gibt nichts, was irgendein Versionsverwaltungssystem dagegen machen kann, |
| 94 | +aber der Standard Git Anwender leidet mehr darunter, weil normalerweise der |
| 95 | +ganze Verlauf geklont wird. |
| 96 | + |
| 97 | +Die Ursachen für die großen Unterschiede sollten ermittelt |
| 98 | +werden. Vielleicht können Dateiformate geändert werden. Kleinere |
| 99 | +Bearbeitungen sollten auch nur minimale Änderungen an nur wenigen Dateien |
| 100 | +bewirken. |
| 101 | + |
| 102 | +Vielleicht ist eher eine Datenbank oder Sicherungs-/Archivierungslösung |
| 103 | +gesucht, nicht ein Versionsverwaltungssystem. Ein Versionsverwaltungssystem |
| 104 | +zum Beispiel ist eine ungeeignete Lösung um Fotos zu verwalten, die |
| 105 | +periodisch von einer Webcam gemacht werden. |
| 106 | + |
| 107 | +Wenn die Dateien sich tatsächlich konstant verändern und sie wirklich |
| 108 | +versioniert werden müssen, ist es eine Möglichkeit Git in zentralisierter |
| 109 | +Form zu verwenden. Jeder kann oberflächliche Klone erstellen, die nur wenig |
| 110 | +oder gar nichts vom Verlauf des Projekts enthalten. Natürlich sind dann |
| 111 | +viele Git Funktionen nicht verfügbar und Änderungen müssen als 'Patches' |
| 112 | +übermittelt werden. Das funktioniert wahrscheinlich ganz gut, wenn auch |
| 113 | +unklar ist, warum jemand die Versionsgeschichte von wahnsinnig instabilen |
| 114 | +Dateien braucht. |
| 115 | + |
| 116 | +Ein anderes Beispiel ist ein Projekt, das von Firmware abhängig ist, welche |
| 117 | +die Form einer großen Binärdatei annimmt. Der Verlauf der Firmware |
| 118 | +interessiert den Anwender nicht und Änderungen lassen sich schlecht |
| 119 | +komprimieren, so blähen Firmwarerevisionen die Größe des 'Repository' |
| 120 | +unnötig auf. |
| 121 | + |
| 122 | +In diesem Fall sollte der Quellcode der Firmware in einem Git 'Repository' |
| 123 | +gehalten werden und die Binärdatei außerhalb des Projekts. Um das Leben zu |
| 124 | +vereinfachen, könnte jemand ein Skript erstellen, das Git benutzt um den |
| 125 | +Quellcode zu klonen und 'rsync' oder einen oberflächlichen Klon für die |
| 126 | +Firmware. |
| 127 | + |
| 128 | +=== Globaler Zähler === |
| 129 | + |
| 130 | +Verschiedene Versionsverwaltungssysteme unterhalten einen Zähler, der mit |
| 131 | +jedem 'Commit' erhöht wird. Git referenziert Änderungen anhand ihres |
| 132 | +SHA1-Hash, was in vielen Fällen besser ist. |
| 133 | + |
| 134 | +Aber einige Leute sind diesen Zähler gewöhnt. Zum Glück ist es einfach, |
| 135 | +Skripte zu schreiben, sodass mit jedem Update das zentrale Git 'Repository' |
| 136 | +einen Zähler erhöht. Vielleicht in Form eines Tags, der mit dem SHA1-Hash |
| 137 | +des letzten 'Commit' verknüpft ist. |
| 138 | + |
| 139 | +Jeder Klon könnte einen solchen Zähler bereitstellen, aber der wäre |
| 140 | +vermutlich nutzlos, denn nur der Zähler des zentralen 'Repository' ist für |
| 141 | +alle relevant. |
| 142 | + |
| 143 | +=== Leere Unterverzeichnisse === |
| 144 | + |
| 145 | +Leere Unterverzeichnisse können nicht überwacht werden. Erstelle eine |
| 146 | +Dummy-Datei um dieses Problem zu umgehen. |
| 147 | + |
| 148 | +Die aktuelle Implementierung von Git, weniger sein Design, ist |
| 149 | +verantwortlich für diesen Pferdefuß. Mit etwas Glück, wenn Git's Verbreitung |
| 150 | +zunimmt und mehr Anwender nach dieser Funktion verlangen, wird sie |
| 151 | +vielleicht implementiert. |
| 152 | + |
| 153 | +=== Initialer 'Commit' === |
| 154 | + |
| 155 | +Ein klischeehafter Computerwissenschaftler zählt von 0 statt von 1. Leider, |
| 156 | +bezogen auf 'Commits', hält sich Git nicht an diese Konvention. Viele |
| 157 | +Kommandos sind mürrisch vor dem intialen 'Commit'. Zusätzlich müssen |
| 158 | +verschiedene Grenzfälle speziell behandelt werden, wie der 'Rebase' eines |
| 159 | +'Branch' mit einem abweichenden initialen 'Commit'. |
| 160 | + |
| 161 | +Git würde davon provitieren, einen Null-'Commit' zu definieren: sofort nach |
| 162 | +dem Erstellen eines 'Repository' wird der 'HEAD' auf eine Zeichenfolge von |
| 163 | +20 Null-Bytes gesetzt. Dieser spezielle 'Commit' repräsentiert einen leeren |
| 164 | +'Tree', ohne Eltern, irgendwann vielleicht der Vorfahr aller Git |
| 165 | +'Repositories'. |
| 166 | + |
| 167 | +Würde dann zum Beispiel *git log* ausgeführt, würde der Anwender darüber |
| 168 | +informiert, daß noch keine 'Commits' gemacht wurden, anstelle mit einem |
| 169 | +fatalen Fehler zu beenden. Stellvertretenden für andere Anweisungen. |
| 170 | + |
| 171 | +Jeder initiale 'Commit' ist dann stillschweigend ein Abkömmling dieses |
| 172 | +Null-'Commits'. |
| 173 | + |
| 174 | +Leider gibt es noch ein paar Problemfälle. Wenn mehrere 'Branches' mit |
| 175 | +unterschiedlichen initialen 'Commits' zusammengeführt und dann ein 'Rebase' |
| 176 | +gemacht wird, ist ein manuelles Eingreifen erforderlich. |
| 177 | + |
| 178 | +=== Eigenarten der Anwendung === |
| 179 | + |
| 180 | +Für die 'Commits' A und B, hängt die Bedeutung der Ausdrücke "A..B" und |
| 181 | +"A...B" davon ab, ob eine Anweisung zwei Endpunkte erwartet oder einen |
| 182 | +Bereich. Siehe *git help diff* und *git help rev-parse*. |
0 commit comments