The Git Index considered harmful

written by Martin Häcker on

Endlich hab ich mal eine ordentliche Quelle gefunden wofür der Index bei GIT gut ist.

Kurz erklärt: Der Index ist eine Vorstufe für jeden Commit. Man comittet zuerst in den index mit git add some_file und comitted dann den index ins repository mit git commit. Es sei denn man sagt git commit some_file in dem fall wird es direkt comitted, oder man wählt eines der anderen kommandos die irgend etwas merkwürdiges mit dem index anstellen, dann weiß man in der Regel gar nicht mehr was Sache ist.

Das hab ich nie verstanden - denn wieso noch mal eine Stufe mehr, wenn man doch sowieso lokal arbeitet und alles was man verbockt hat wieder verändern kann bevor man es pusht?

Ah well. Es gibt offenbar drei Hauptgründe:

  1. Der Index hilft besser mit einer dirty workspace zu leben
  2. Der Index hilft noch mehr über einen commit nachzudenken und ihn zu verfeinern bevor man ihn macht
  3. Linux Torvalds hat den Index erfunden und will ihn behalten

Zu 1. Eine Dirty Workspace ist manchmal praktisch

Die Idee ist dass es Änderungen gibt die jeder in seinem lokalen Checkout hat aber niemand einchecken will. Z.B. die debug-flags, oder der andere Pfad in einem makefile. Es ist viel komfortabler jedes mal zu sagen was man committen will, als jedes mal daran zu denken was man nicht committen will. Ganz davon abgesehen dass man irgendwan nicht daran denkt das man etwas nicht machen wollte. Been there, done that.

Dieses Problem hab ich auch ab und an. Zum Beispiel dieses komische File dass einen Build-Counter für den Build-Bot enthält. Eigentlich sollte das gar nicht in das repository. Aber dann war es doch drinnen. Und es nervte eigentlich nur, weil jeder lokale compile es erhöht hat. Und wenn es dann doch mal jemand comitted hat, gab es für jeden anderen natürlich einen konflikt. Sehr nervig. Oder der Debug-Flag, den man irgendwo tief in einem Framework einschalten musste. Den will ich natürlich auch nicht in einem Release haben.

Ich finde allerdings dass der Index überhaupt keine gute Lösung für derartige Probleme ist. Wenn ich lokale changes habe die ich nicht committen will, dann würde ich die viel lieber als "ignore" markieren, als jedes mal alles andere zu committen.

Ein bekannter formulierte das mal so, dass er oft code hat der den Code Testet den er comittet - und dass er den nicht im Repository haben will. Diese Variante des Arguments finde ich allerdings noch schrecklicher, weil ich in jedem Fall den Testcode auch im Repository haben will. Gerade. Damit ich später regressionstests durchführen kann. Automatisiert natürlich. Alleine der Gedanke dass der Testcode gleich wieder weggeworfen wird... schauder

Zu 2. Erst noch mal drüber nachdenken ist eine gute Idee

Das finde ich ein wesentlich besseres Argument: Man soll sich über einen Commit Gedanken machen bevor man ihn tut. Und damit man das tut soll man genau auswählen was in ihn hinein kommt.

Commendable.

Allerdings nur wenn man nicht richtig darüber nachdenkt. Denn git ist ja ein distributed VCS. Das heißt, alle commits sind erst einmal lokal. Und kommandos die den letzten commit einfach rückgängig machen oder noch mal neu gibt es jede menge. Sogar um mehrere History-Schritte zurück zu kommen. (Und die braucht es sowieso, denn selbst mit Index macht man immer wieder Fehler.)

Oops.

Also bleibt übrig: der Index ist ein zusätzlicher Abstraktionsschritt der keinen Wert hinzufügt, sondern nur kompliziertere Bedienung erzeugt.

Hm. Das heißt natürlich frei nach Occam, dass man den Index als überflüssiges Konzept 'über die klinge springen lassen' sollte.

Zu 3. Linus hats erfunden und will es behalten

Dass scheint mir der eigentliche Grund zu sein. Wie Torvalds es selber schon gesagt hat: "I have an ego the size of a small planet". Und daher wird es den Index auch weiter geben. Auch wenn es eine schlechte Idee ist. Und die git-Benutzer werden sich damit arrangieren, da niemand die Lust hat das wirklich auszufechten.

Zumindest ist das meine Einschätzung.

Schade eigentlich.

Hier mein Vorschlag: Für alle Index-Liebhaber gibt es eine Option in ihrer .gitrc mit der sie den Index und wie er heute ist aktivieren können. Für alle anderen gibt es den vernünftigen default wert, der den Index einfach wie bei allen anderen Versionskontrollsystemen versteckt. Das macht man am besten so, dass bei einem Update, die .gitrc so verändert wird, dass alle die git updaten den index behalten und alle die git neu einrichten den index explizit aktivieren müssen. Dass sollte am wenigsten Geschrei erzeugen.

Kommentare bitte per mail an spamfaenger ät gmx.de

Update: Es gibt noch viel mehr leute die mit der Git UI probleme haben. :)