Benutzer:Lord Horazont/Tutorial Versionskontrolle mit GIT

Aus DGL Wiki
< Benutzer:Lord Horazont
Version vom 23. September 2011, 17:51 Uhr von Lord horazont (Diskussion | Beiträge) (Working draft)

(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

Versionskontrolle mit git

Hallo und herzlich willkommen zu meinem dritten Tutorial. Heute soll's um Versionskontrolle gehen und zwar demonstriert anhand von git. Warum überhaupt Versionskontrolle? Warum für Hobbyprojekte? Was ist git? Wie macht man das? – diese und andere Fragen werde ich (hoffentlich) beantworten.

Theorie der Versionskontrolle

Nun, jeder der schon einmal einen Wikiartikel geschrieben hat, hatte schon indirekt Kontakt mit Versionskontrolle. Sowas ist nämlich in jedes MediaWiki eingebaut. Immer, wenn man einen Artikel bearbeitet, wird die vorherige Version erhalten, man kann sie später anschauen oder Änderungen rückgängig machen.

Dies gibts nicht nur für Webseiten wie unser Wiki, sondern, in anderer Form, auch für Projekte. Viele werden schonmal irgendwo SVN oder CVS gehört haben, weniger von GIT oder Mercurial. Diese vier sind vermutlich die populärsten Versionskontrolle-Werkzeuge, die im Moment im Einsatz sind.

Häufige Probleme…

Problem 1: Mist gebaut?

Der große Vorteil der Versionskontrolle liegt auf der Hand. Habt ihr schonmal selbstsicher angefangen, an einem Feature zu arbeiten, dann festgestellt, dass es irgendwie nicht ganz so gut läuft wie erwartet und zum schluss einen Haufen Konflikte im Code gehabt? Da hilft meist nur noch eins: Rückgängig drücken, und zwar oft. Mist! Das Undo-Limit der IDE ist erreicht, aber nichtmal die Hälfte der Änderungen wurden rückgängig gemacht. Dann hat man noch die Möglichkeit, auf ein Backup zurückzugreifen (falls das überhaupt existiert), oder eben alles von Hand wieder Rückgängig machen.

Problem 2: Zusammenarbeit

Anderes Szenario: Man hat ein Projekt, was gut läuft und was andere (Programmierer) interessant finden. Sie möchten Beitragen, aber natürlich hat man eher wenig Lust immer Archive mit allen Sourcedateien per Mail oder sonstwas zu verschicken. Auch will man den Leuten nicht unbedingt Schreibzugriff auf den eigenen Rechner geben. Also könnte man immer noch, um das Datenvolumen zu reduzieren, Patches verschicken.

… und ihre Beseitigung durch Versionskontrolle

Aus beiden Szenarien gibt es einen gemeinsamen Ausweg: Versionskontrolle und Repositories solcher müssen her!

Anhand von git sei nun im folgenden gezeigt, wie man die beiden genannten Probleme umgeht. Aber wir wollen von Grund auf anfangen, damit ihr das ganze gleich sofort ausprobieren könnt. Dazu beginnen wir damit, wie man Git verwendet. Es sei vorrausgesetzt, dass ihr mit dem Terminal (oder der git-bash, was nichts weiter als eine Bash mit Git für Windows ist) umgehen könnt. Außerdem sollte Git bzw. die Git-Bash natürlich installiert sein ;).

Ein Git-Repository anlegen und befüllen

Das ist recht einfach. Wir wechseln (mit cd) in das Verzeichnis, wo wir ein Git-Repository anlegen wollen. Das ist im optimalfall leer oder das Wurzelverzeichnis unseres Projektes. Dann initialisieren wir ein git Repo mit:

$ git init

War einfach, oder? Jetzt können wir schauen, was git so sagt (vorrausgesetzt, es sind schon Dateien im Verzeichnis, sonst erstmal ein Projekt oder so reinkopieren):

$ git status

Das sollte eine Ausgabe ähnlich dieser erzeugen:

# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	a
#	b
nothing added to commit but untracked files present (use "git add" to track)

Wobei anstatt a und b bei euch vermutlich andere Dateien und Verzeichnisse aufgelistet sind. Diese können wir nun mit:

$ git add file1 file2 …

hinzufügen. Das geht aber auch einfacher:

$ git add directory/* # fügt alle Dateien im Verzeichnis directory hinzu (mit Unterverzeichnissen)
$ git add directory # wie oben
$ git add *.c # fügt alle Dateien, die auf .c enden und im Wurzelverzeichnis liegen hinzu
$ git add directory/*.c # könnt ihr sicher erraten: fügt alle Dateien, die auf *.c enden und in directory liegen hinzu (sollte dort ein Ordner auf .c 

enden, wird dieser auch hinzugefügt…)

$ git add -A # fügt *alle* dateien, die es im Ordner finden kann, hinzu. Kann zu viel sein, evtl. mit git rm --cached wieder welche entfernen.

Soweit. Nun haben wir git mitgeteilt, dass wir diese Dateien hinzufügen wollen. Das müssen wir noch committen, sozusagen „amtlich“ machen:

$ git commit -v

Das wird euren bevorzugten Terminal-Editor öffnen und ihr könnt eine Commit-Message eingeben, die später im Log zu diesem „Commit“ auftauchen wird. Ein „Commit“ ist sozusagen ein Satz an Änderungen, der logisch zusammen gehört. Was logisch zusammen gehört, definiert sich daran, was ihr zusammen committed ;). Wenn nichts schief gegangen ist, wird git sowas sagen wie:

[master (root-commit) 050a498] * Bla
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 bla/bakery/bread
 create mode 100644 bla/cookie
 create mode 100644 bla/keks
 create mode 100644 c.c

Ansonsten sollte die Fehlermeldung aufschluss darüber geben, was nicht geklappt hat. Eventuell möchte git, dass ihr ihm sagt, wer ihr seid. Das tut ihr mit den Befehlen, die es euch da vorschlägt. Diese Informationen werden in die Commits mit eingebunden, damit man diese den Entwicklern zuordnen kann.

Änderungen durchführen und committen

Nun können wir an unserem Code rumschreiben. Wenn wir einen Schritt weiter zu unserem Ziel gekommen sind, können wir die Änderungen ins Repo committen. Ich mache das meist, wenn ich kompilierfähigen Code habe oder wenn ich einen größeren Schritt erledigt habe oder wenn ich von einer logischen Einheit des Codes in eine andere wechsle (z.B. unterschiedliche Packages oder Module). Jetzt können wir entweder alle Dateien, die wir geändert oder neu hinzugefügt haben mit

$ git add path/to/file.pp path/to/file2.pp

“stagen”, d.h. für den Commit vorsehen, oder wir nutzen

$ git commit -av

wobei das “a” in der Kommandozeile sagt, dass es automatisch alle geänderten Dateien mit in den Commit aufnehmen soll. Beachtet aber, dass es neu erstellte Dateien nicht als “changed” sondern als “untracked” sieht, also werden sie nicht beachtet. Neu erstellte Dateien muss man explizit mit

$ git add path/to/new/file.pp

ankündigen. Das kann man aber ohne Probleme zusammen mit git commit -av benutzen, sodass man nur die neu erstellten Dateien mit git add stage't, aber die anderen mit git commit -av.

$ git log

sollte nun schon ein paar schöne Commits ausgeben.

Pushs, Fetchs, Merges, Pulls und Branches

Ähhh. Was? Ok, der Reihe nach.

“A successful git branching model”

Auf dieser Seite bin ich auf ein sehr hilfreiches Arbeitsmodell für das Arbeiten mit Branches unter Git gestoßen. Das könnt ihr euch am besten Ausdrucken und an die Wand pinnen.