Versionsverwaltung mit git

Wie so oft in diesem Blog sprechen wir natürlich über ein technisches Thema – und zwar geht es um Versionsverwaltung. Vornehmlich im Bereich Softwareentwicklung angesiedelt kann man damit seinen Quellcode verwalten. Warum braucht man dazu ein eigenes Programm? Man hat die Dateien ja da und kann ab und zu ein Backup machen, oder?

Ganz so einfach ist es doch nicht, denn man kommt mit dieser Vorgehensweise sehr schnell an seine Grenzen. Ein paar Beispiele: mit einer einfachen Dateiverwaltung wird es teilweise unmöglich, im Team zu arbeiten, weil es zwangsläufig dazu kommt, dass mehr als eine Person an der gleichen Datei arbeiten muss. Software ist NIE fertig, es wird immer wieder Änderungen oder Bugfixes geben. Was macht man, wenn man zu einer älteren Version zurück will oder nur mal die Unterschiede zwischen zwei Versionen vergleichen will? Verbreite ich meinen Quellcode sinnvoll, damit mein Opensource-Projekt aktive Mitstreiter bekommt und diese ihr Änderungen auch wieder zu mir zurückfließen lassen können? Diese Liste kann man beliebig erweitern, und es wird immer wieder herauskommen, dass eine Versionsverwaltung doch immer der elegantere Weg sein wird.

Das haben Entwickler ziemlich zeitig bemerkt und entsprechende Programme entworfen, die einen bei diesem Problem unterstützen. Heraus kamen Systeme wie cvs oder Subversion. Die sind schon ganz gut, haben aber immer ein großes Problem: sie brauchen einen Server. Und das veringert die Geschwindigkeit sehr deutlich. Hinzu kommt, dass Arbeit von Unterwegs erheblich erschwert wird, weil man nur bei einer Verbindung zum Server Zugriff auf die Historie einer Datei hat.

Was mich persönlich am meisten gestört hat, war der Umstand, dass die bestehenden Systeme nur sehr schlecht mergen – also zusammenführen mehrerer Änderungen in der gleichen Datei – können. Auch sehr unschön war das Branching – also das Anlegen eigener Entwicklungszweige.

Git ist hier äußerst robust und bekommt nur Probleme, wenn man wirklich die gleiche Zeile verändert. Entwickelt wurde das System von keinem anderen als Linux Torvalds, dem Erfinder von Linux. Ihm war die Verwaltung des Linux Quellcodes schon lange ein Dorn im Auge und am Markt gab es kein Tool, was seinen Ansprüchen genügte. Also entwickelte er ein entsprechendes System selbst – heraus kam git.

Die großen Vorteile: Die Repositories liegen lokal auf jedem Rechner, merge-Prozesse sind sehr schnell und auch sehr genau und das Anlegen von Branches sowie der Wechseln zwischen ihnen stellt kein Problem mehr dar. Es zeigt sich einfach, dass man viel autarker arbeiten kann, da man alle benötigten Daten auf seinem PC hat und erst dann mit dem Server kommunizieren muss, wenn man Commits übertragen oder Updates ziehen möchte. Sehr schön gelöst ist auch die Aufbewahrung der Meta-Daten. Liegt bei Subversion oder cvs in jedem Ordner ein Unterordner mit den Daten, so ist es bei git pro Repository nur ein einziger Ordner, und der liegt im Hauptverzeichnis des Projekts. Möchte man also Dateien versenden, so kann man diese direkt nehmen und muss nicht erst anfangen, jeden Ordner einzeln zu reinigen. Wer schon einmal ein Subversion Projekt von Meta-Daten befreit hat, weiß, wovon ich spreche 😉

Um meine Einleitung zu diesem Artikel noch zu relativieren: Man kann mit git und auch anderen Versionskontrollsystemen jede Art von Datei verwalten. Es gibt z.B. viele Grafiker, die ihre Projekte mit git verwalten, weil sie dann einfach in der Historie vor und zurück springen können. Selbst Backup-Lösungen kann man damit aufbauen. Am effizientesten funktionieren die Systeme aber noch immer mit reinen Textdateien.

Zum Thema Versionskontrollsysteme sei euch übrigens auch folgender Podcast sehr ans Herz gelegt:
CRE 130 – Verteilte Versionskontrollsysteme

Links
git

[Quicktip] cgi Scripte mit Plesk

Am letzten Wochenende habe ich das erste mal in meinem Leben ein cgi Script verwendet. In Zeiten von php – welches im Prinzip auch cgi ist – braucht man derartige Tools einfach nicht mehr so wirklich. Der Vorteil ist aber ganz klar: cgi Programme sind schnell – sofern wir von c oder c++ sprechen. Es wird wohl kein php, ruby, python oder perl Script geben, welches mit einem sauber in C aufgesetzten cgi mithalten kann. Dafür hat man aber den Aufwand, dass man erst kompilieren muss, um das Programm verwenden zu können. Natürlich kann man aber auch alle weiteren Script- oder kompilierten Sprachen als cgi verwenden. Bei interpretierten Sprachen ist dies aber deutlich langsamer, als wenn man diese per Apache Modul betreibt, da sonst bei jedem Aufruf erst einmal der Interpreter initialisiert werden muss.

Egal, ich war dabei, cgit (ein grafisches Frontend für lokale git-Repositories) aufzusetzen – da kommt auch nochmal ein Blogeintrag zu. Nachdem ich mit der Compilierung und Installation durch war, legte ich in Plesk die Domain an, aktivierte in den Domaineinstellungen, dass cgi-Scripte unterstützt werden sollen – und dann stand ich da…

Einfach in den httpdocs Ordner der Domain werfen brachte nichts, dann war die Datei als Download verfügbar. Mir fiel dann schnell der cgi-bin Ordner auf, der sich in der Ordnerstruktur neben den httpdocs und httpsdocs Ordnern befindet. Nur wie ruft man diese auf? Nach etwas Probierarbeit kam ich dann drauf:

http://www.domain.de/cgi-bin/script.cgi

Eigentlich ganz einfach, aber naja 😉

Nachdem ich das herausgefunden hatte, lief mein Tool natürlich trotzdem nicht. Über die Console lief es wunderbar, nur eben nicht im Browser. Dann wurde mir klar, dass das nur noch mit Benutzerrechten zu tun haben kann – und so war es auch. Es ist wichtig (zumindest wenn man mit Plesk arbeitet), dass das cgi Script der Gruppe “psacln” gehört. Außerdem habe ich auch den Benutzer der Domain als Inhaber der Datei festgelegt, was aber wohl nicht zwingend notwendig ist.

[Quicktip] GIT Commit/Merge auf github rückgängig machen

Folgendes Problem: Ihr habt ein paar Änderungen commited und auch schon gepushed – in meinem Fall zu github -, merkt dann aber, dass ihr was falsches commited habt. Was nun?

Zuerst könnt ihr mit eurem GIT Client auf die Version resetten, die noch ok war. Oder ihr macht das per Git-Bash:

git reset --hard [Hashwert des gültigen Commits]

Damit setzt ihr euren Stand direkt auf diesen Commit zurück. Achtung! Wenn ihr den Parameter –hard verwendet werden sämtliche Änderungen überschrieben – und alle nachfolgenden Commits werden gelöscht!

Anschließend führt ihr ein

git push -f

aus und schon wird der Reset auch an Github oder evtl. andere entfernte Repositories übertragen. Achtung auch hier: die nachfolgende History wird gelöscht, auch von github. Wenn ihr den Parameter -f (für “force”) weglasst, so wird euch der Push verweigert, da ihr ja einen älteren Stand als im Repository pushen wollt. Daher ist er zwingend nötig.