blog · git · desktop · images · contact


Git benutzen, ohne dass es jemand merkt

2011-02-19

Im Moment habe ich die Vorgabe, dass mein Code in ein CVS-Repository soll. Das ist so, weil das so ist und schon immer so war. Okay. Auf der anderen Seite verwende ich seit ungefähr zwei Jahren nur noch Git -- und zwar intensiv und für fast alles, was mir über den Weg läuft. Das verändert langfristig die Denk- und Arbeitsweise. Wer Git schon einmal länger als zwei Wochen benutzt hat, wird wissen, was ich meine. Mir geht es hier aber gar nicht so sehr darum, was Git denn nun alles besser kann oder nicht. Das kann man sich bei Bedarf bei den üblichen Anlaufstellen anschauen:

Stattdessen will ich einen Weg finden, wie ich trotzdem auf irgendeine Art Git nutzen kann, obwohl CVS die offizielle Vorgabe ist.

Wenn es nur darum ginge, dass alles in CVS landet, wäre es auch nicht so das Problem. Ähnlich wie mit SVN (siehe frühere Postings) kann man auch CVS mit Git ansprechen. Ich könnte also einfach Git als CVS-Client nutzen und alles wäre gut.

Leider ist eine weitere Vorgabe, dass eine bestimmte IDE benutzt wird. Und zwar dergestalt, dass am Ende das gesamte Installationsverzeichnis dieser IDE in ein Archiv gepackt wird und dann anderen Entwicklern zur Verfügung gestellt werden kann. In diesem Paket muss auch der in der IDE eingebaute CVS-Client konfiguriert und voll funktionsfähig sein. Das muss alles bestimmten Richtlinien folgen. Wenn ich da nun anfange und innerhalb der IDE mit Git rumfuchtele, endet das in Chaos und ich verletze die Vorgaben. Ich komme also nicht komplett an CVS vorbei.

Welche Möglichkeit habe ich nun, trotzdem Git nutzen zu können? Zumindest parallel? So, dass es die IDE nicht merkt?

Die Idee ist, die Umgebungsvariablen "$GIT_DIR" und "$GIT_WORK_TREE" zu nutzen, um das eigentliche Git-Repository an eine isolierte Stelle im Dateisystem zu bringen. Der Arbeitsbereich bleibt dabei an der alten Position.

~
|-- git
|   |-- projectA.git
|   |-- projectB.git
|   `-- projectC.git
`-- ide
    |-- bin
    |-- etc
    |-- usr
    `-- workspace
        |-- projectA
        |-- projectB
        `-- projectC

In "~/ide/workspace/projectA" liegt der Quellcode eines Projekts. Hierauf greift die IDE zu und hier ändere ich auch meine Dateien aus der IDE heraus. Der gesamte "~/ide"-Zweig soll später als Archiv zur Verfügung gestellt werden. In "~/git" hingegen werden sich Bare-Repositories befinden.

Nun kann ich folgendes tun:

$ export GIT_DIR=~/git/projectA.git
$ export GIT_WORK_TREE=~/ide/workspace/projectA

Git greift nun zum Ablegen seiner Meta-Daten auf "~/git/projectA.git" zurück, wohingegen es den Arbeitsbereich in "~/ide/workspace/projectA" vorfindet. Vorher muss man natürlich noch die Bare-Repositories anlegen:

$ cd "$GIT_DIR"
$ git init --bare

So vorbereitet kann ich, obwohl ich mich in "~/ide/workspace/projectA" befinde, in das isolierte Repository committen:

$ cd ~/ide/workspace/projectA
$ git add .
$ git commit -m 'Initialer Import.'
$ [work, commit, work, commit]
$ git log --oneline --decorate
fbf57da (HEAD, master) Alle Bugs gefixt, auch zukünftige.
6326128 Superfeature.
7483d16 Initialer Import.

Dabei wird keine einzige Git-spezifische Datei im Arbeitsverzeichnis angelegt. Die IDE bekommt nicht einmal mit, dass Git überhaupt existiert. Sie sieht nur ihre eigenen Dateien, die im Arbeitsverzeichnis liegen. Im Dateisystem gibt es unterhalb von "~/ide" keinen einzigen Hinweis darauf, dass Git-Repositories in "~/git" benutzt werden -- nur die beiden Umgebungsvariablen stellen diese Verbindung her.

Das heißt, ich kann innerhalb der IDE entwickeln und meinen Code schreiben. Das kann ich dann an der IDE vorbei nach Git committen. Wenn ich der Meinung bin, "das hier ist jetzt ein guter Zustand", dann comitte ich aus der IDE heraus nach CVS -- wovon Git wiederum nichts mitbekommt.

Fast zumindest. CVS hat die schöne Angewohnheit, überall Unterverzeichnisse namens "CVS" hinzuschmeißen. Die sollte man natürlich tunlichst in Git ignorieren:

$ cd ~/git/projectA.git/info/
$ echo CVS >> exclude

Ähnlich könnte man auch andere Dateien ignorieren, die die IDE nur für den eigenen Gebrauch anlegt, die aber nichts in einer Versionsverwaltung zu suchen hätten.

Letztenendes muss ich mir also nur einen besonderen Starter für ein Terminal anlegen, der automatisch die beiden Umgebungsvariablen richtig setzt. Dann kann ich in diesem Terminal alle Vorteile von Git ausschöpfen. Dabei bin ich zu jedem Zeitpunkt konform mit den Vorgaben. Lediglich nachdem Git Dateien im Arbeitsverzeichnis geändert hat, sollte ich in der IDE auf "Refresh" drücken. ;) Der einzige Nachteil ist, dass ich pro Projekt einen eigenen Starter für ein Terminal brauche.

Comments?