git ist das Versions-Kontroll-System, das derzeit unter anderem für den Kernel Linux verwendet wird.

Homepage: http://git-scm.com/

Lizenz: GPLv2

Tipps & Tricks

Mini-Howto

Wenn man bei einem Projekt mitarbeiten will, holt man sich erst einmal einen Klon ("clone") des Projekts auf den eigenen Rechner. Dazu verwendet man z.B. den Befehl "git clone git://git.sv.nongnu.org/akfavatar.git". Dann ändert man, was man ändern möchte. Wenn es nicht so ganz klappt, kann man eine Datei auch wieder in einen früheren Zustand zurückversetzen, zum Beispiel mit "git checkout -- avatar.c". Man kann sich zwischendurch seine Änderungen auch anzeigen lassen: "git diff". Wenn nun alles so ist, wie man es haben möchte, dann sollte man erstmal die bearbeiteten Dateien zum Einpflegen ("Einchecken") vorbereiten: "git add avatar.c akfavatar.h", und dann kann man seine Änderungen einpflegen ("einchecken"): "git commit -m "dies und jenes geändert"".

Das bisher erläuterte läuft alles auf der lokalen Kopie, die man auf den eigenen Rechner geladen hat. Wenn man seine Änderungen nun an den oder die Hauptentwickler schicken will, kann man sich eine Differenzdatei ("Patch") erstellen lassen: "git format-patch origin/master". Den schickt man dann an die Hauptentwickler.

Um mit der Entwicklung der anderen mitzuhalten, kann man sich mit dem Befehl "git pull origin" seine Kopie aktualisieren. Git weiß dann schon, wo es das herbekommt. Man muss sich dafür nur in dem Verzeichnis befinden, das man sich vorher schon einmal mit "clone" geholt hat.

Kurzreferenz

git init

git add [Datei/Verzeichnis]

git commit -a -m '[Kommentar]'

git checkout [Version oder Branch]

git clone [--bare]

git pull [Repository]

git push [Repository]

git branch [name]

git merge [branch]

git branch -d/-D [branch]

git diff [version] [version]

git log [-n 10]

git status

git gc

git mv [alter Name] [neuer Name]

git rm [name]

git tag [name]

git ls-files

Tutorial für Einsteiger

Ziel dieses Tutorial ist es, Einsteigern einen kleinen Einblick in Git zu geben.

Da es sich bei Git um ein dezentralisiertes Versions-Kontroll-System handelt, ist es möglich, Git nur "lokal" oder auch über mehrere Repositorys zu verwenden. Wir werden mit den lokalen Operationen anfangen.

Die Grundidee ist, alle Dateien in einem Aufbewahrungsort (Repository) zu verwalten. Hier werden die Dateien und deren Änderungen gespeichert und versioniert.

Mein kleines Projekt

Im folgenden Beispiel wird ein neues Projektverzeichnis eingerichtet, dieses soll in Zukunft versioniert werden.

user@host:~$ mkdir ~/MeinProjekt
user@host:~$ cd ~/MeinProjekt/

user@host:~/MeinProjekt$ git init
Initialized empty Git repository in /home/user/MeinProjekt/.git/
user@host:~/MeinProjekt$ 

Herzlichen Glückwunsch. Sie haben ihr eigenes Git-Repository erstellt! ;-)

Der nächste Schritt ist die Konfiguration. Im folgenden werden Namen und E-Mail-Adresse gesetzt.

user@host:~/MeinProjekt$ git config user.name "Stefan"
user@host:~/MeinProjekt$ git config user.email "user@local"

Was hat git jetzt eigentlich gemacht?

Git hat im Verzeichnis /home/user/MeinProjekt ein neues, verstecktes Verzeichnis angelegt.

/home/user/MeinProjekt/.git

Mit dem git config wurde die Konfigurationsdatei bearbeitet

/home/user/MeinProjekt/.git/config

und um folgende Einträge erweitert.

[user]
        name = Stefan
        email = user@local

Die ersten Dateien

Wir werden nun anfangen, etwas zu arbeiten. Die ersten Dateien entstehen. Wir erstellen zuerst drei Dateien:

user@host:~/MeinProjekt$ echo "Text 1 in Datei 1" > Datei_1.txt
user@host:~/MeinProjekt$ echo "Text 1 in Datei 2" > Datei_2.txt
user@host:~/MeinProjekt$ echo "Text 1 in Datei 3" > Datei_3.txt

Diese sollen nun im Repository gespeichert werden.

user@host:~/MeinProjekt$ git add Datei_1.txt 
user@host:~/MeinProjekt$ git add Datei_2.txt 
user@host:~/MeinProjekt$ git add Datei_3.txt 

user@host:~/MeinProjekt$ git commit -m "Meine ersten Dateien"
[master (root-commit) 636db54] Meine ersten Dateien
 3 files changed, 3 insertions(+), 0 deletions(-)
 create mode 100644 Datei_1.txt
 create mode 100644 Datei_2.txt
 create mode 100644 Datei_3.txt

Die ersten Dateien

Lokal werden wir nun Dateien ändern:

user@host:~/MeinProjekt$ echo "Text 1 in Datei 1 - ändern" > Datei_1.txt
user@host:~/MeinProjekt$ echo "Text 2 in Datei 2" >> Datei_2.txt
user@host:~/MeinProjekt$ echo "Text 3 in Datei 2" >> Datei_2.txt
user@host:~/MeinProjekt$ echo "Text 2 in Datei 3" >> Datei_3.txt

Nun können wir uns die Änderungen zwischen lokalem Dateisystem und Index ansehen:

user@host:~/MeinProjekt$ git diff
index 38f57e1..a16a66a 100644
--- a/Datei_1.txt
+++ b/Datei_1.txt
@@ -1 +1 @@
-Text 1 in Datei 1
+Text 1 in Datei 1 - ändern
diff --git a/Datei_2.txt b/Datei_2.txt
index 1e10b21..6ec80e6 100644
--- a/Datei_2.txt
+++ b/Datei_2.txt
@@ -1 +1,3 @@
 Text 1 in Datei 2
+Text 2 in Datei 2
+Text 3 in Datei 2
diff --git a/Datei_3.txt b/Datei_3.txt
index 38d7991..40cbf6a 100644
--- a/Datei_3.txt
+++ b/Datei_3.txt
@@ -1 +1,2 @@
 Text 1 in Datei 3
+Text 2 in Datei 3

Die Änderungen können über "add" zum Index hinzugefügt werden. Der "commit"-Befehl übernimmt die Informationen aus dem Index in das Repository.

user@host:~/MeinProjekt$ git add Datei_1.txt 
user@host:~/MeinProjekt$ git add Datei_2.txt 
user@host:~/MeinProjekt$ git add Datei_3.txt 
user@host:~/MeinProjekt$ git commit -m "Einige Änderungen"
[master b8bb6d3] Einige Änderungen
 3 files changed, 4 insertions(+), 1 deletions(-)

Nun sind auch diese Änderungen im Repository gespeichert.

user@host:~/MeinProjekt$ git log
commit b8bb6d33acf5a0f911055e64bb222f1a912c2a0a
Author: Stefan <user@local>
Date:   Sat Jan 30 15:46:43 2010 +0100

    Einige Änderungen

commit 636db5487141a7e857c6c60f0fde09fefb1f7ab8
Author: Stefan <user@local>
Date:   Sat Jan 30 15:35:33 2010 +0100

    Meine ersten Dateien

Repository mit http veröffentlichen

 git clone --bare /source /source_bare
 cd /source_bare
 git --bare update-server-info
 cp hooks/post-update.sample hooks/post-update
 chmod a+x hooks/post-update

...spätestens jetzt Apache-Webserver installieren...

 sudo mkdir /var/www/olaf
 sudo chown olaf.olaf /var/www/olaf
 mv /home/olaf/source_bare /var/www/olaf

Mit einem bereits bestehenden Repository auf SourceForge.net umziehen

Hat man bereits ein existierendes lokales Repository und will dieses auf SourceForge.net veröffentlichen, hat man das Problem, nur eingeschränkt Zugriff auf das Dateisystem zu haben. Details siehe:

Der einfachste Weg verläuft deshalb über Git selbst:

Zunächst herausfinden, wie der der Branch heißt, den man veröffentlichen will:

 or@bigbox:~/var/bibletime$ git branch
 * olaf

In diesem Fall also "olaf". Normalerweise ist es aber "master". Das ist hier aber ein klein bisschen anders in meinem Fall. Dann muss ich ggf. andere, entfernte Repositorys entfernen aus dem "Gedächtnis" von Git.

 or@bigbox:~/var/bibletime$ git remote rm origin

Jetzt füge ich das entfernte ("remote") Repository von sourceforge.net hin zu (in das "Gedächtnis" von) Git.

 or@bigbox:~/var/bibletime$ git remote add origin ssh://radicke@bibletimeofolaf.git.sourceforge.net/gitroot/bibletimeofolaf/

Jetzt kann ich mit einem einfachem "push" mein Repository hochschieben. Ich brauche keinen Zielrechner anzugeben. Den habe ich Git zuvor mit "remote add" bekanntgegeben. Mit "origin" ist das Repository bei git.sourceforge.net gemeint.

 or@bigbox:~/var/bibletime$ git push -u origin olaf
 radicke@bibletimeofolaf.git.sourceforge.net's password:
 Counting objects: 31054, done.
 Compressing objects: 100% (5153/5153), done.
 Writing objects: 100% (31054/31054), 26.91 MiB | 100 KiB/s, done.
 Total 31054 (delta 24155), reused 30643 (delta 23802)
 To ssh://radicke@bibletimeofolaf.git.sourceforge.net/gitroot/bibletimeofolaf/bibletimeofolaf
  * [new branch]      olaf -> olaf
 Branch olaf set up to track remote branch olaf from origin.

Der Prozess kann je nach Größe einige Minuten dauern.

Mit origin-Branches arbeiten

Wenn wir tatsächlich den Weg in den letzten Abschnitt gegangen sind, werden wir (oder andere) feststellen, daß nach einem "clone" das lokale Repository leer ist. Das hängt damit zusammen, daß es aktuell keinen "master"-Branch gibt. Es gibt immer wieder einmal Szenarien, bei denen wir die Versionszweige ("branches") anderer Entwickler erhalten wollen, die nicht "master" sind (mit "master" ist der Hauptzweig gemeint; bei SVN oder CVS nennt man das meist "trunk"). Zum Beispiel, wenn ein Entwickler einen versuchsweisen Versionszeig erstellt, um einen Test durchzuführen. Dann kann es passieren, daß wir diesen anschauen und bei uns lokal bearbeiten wollen, um eigene Tests zu machen. Soweit die Theorie. Jetzt zum konkreten Beispiel:

Tun wir so, als würden wir uns einen frischen "clone" ziehen von dem im Kapitel oben angelegten Repository.

 olaf@gallien-197:~/var$ git clone git://bibletimeofolaf.git.sourceforge.net/gitroot/bibletimeofolaf/bibletimeofolaf/
 Initialized empty Git repository in /atix/home/olaf/var/bibletimeofolaf/.git/
 remote: Counting objects: 31054, done.
 remote: Compressing objects: 100% (4800/4800), done.
 remote: Total 31054 (delta 24155), reused 31054 (delta 24155)
 Receiving objects: 100% (31054/31054), 26.52 MiB | 826 KiB/s, done.
 Resolving deltas: 100% (24155/24155), done.
 warning: remote HEAD refers to nonexistent ref, unable to checkout.

Die letze Zeile warnt uns schon, daß etwas schiefgegangen ist. Wechseln wir also erstmal in unseren Repository-Clone...

 olaf@gallien-197:~/var$ cd ./bibletimeofolaf/
 olaf@gallien-197:~/var/bibletimeofolaf$ git branch
 * (no branch)

Wenn wir ein "ls" machen oder ein "git branch", werden wir nur gähnende Leere sehen. Es ist aber nicht so, daß das Repository tatsächlich leer ist! Die Zweige ("branches"), die von anderen Entwiklern im entfernten ("remote") Repository erstellt ("pushed") wurden, stehen uns zur verfügung. Wir müssen sie aber explizit "auschecken". Mit "origin" ist das entfernte Repository gemeint.

 olaf@gallien-197:~/var/bibletimeofolaf$ git checkout origin/olaf
 Checking out files: 100% (1082/1082), done.
 Note: checking out 'origin/olaf'.
 
 You are in 'detached HEAD' state. You can look around, make experimental
 changes and commit them, and you can discard any commits you make in this
 state without impacting any branches by performing another checkout.
 
 If you want to create a new branch to retain commits you create, you may
 do so (now or later) by using -b with the checkout command again. Example:
 
   git checkout -b new_branch_name
 
 HEAD is now at 90825ea... set small margins for small devs.

Jetzt sehen wir auch tatsächlich unsere Daten, haben aber immer noch keinen eigenen Versionzweig ("branch"):

 olaf@gallien-197:~/var/bibletimeofolaf$ ls
 CMakeLists.txt ChangeLog  LICENSE  Makefile  README  README_ATER_GUI.txt  build-debug.sh  build-release.sh  cmake  docs  i18n  pics  src
 olaf@gallien-197:~/var/bibletimeofolaf$ git branch
 * (no branch)

Das lässt sich aber schnell ändern (mit "branch")...

 olaf@gallien-197:~/var/bibletimeofolaf$ git branch master
 olaf@gallien-197:~/var/bibletimeofolaf$ git branch
 * (no branch)
   master
 olaf@gallien-197:~/var/bibletimeofolaf$ git checkout master
 Switched to branch 'master'
 olaf@gallien-197:~/var/bibletimeofolaf$ ls
 CMakeLists.txt ChangeLog  LICENSE  Makefile  README  README_ATER_GUI.txt  build-debug.sh  build-release.sh  cmake  docs  i18n  pics  src

Jetzt schieben ("push") wir das in die öffentlichen Repositorys von sourceforge.net....

 olaf@gallien-197:~/var/bibletimeofolaf$ git push --all ssh://radicke@bibletimeofolaf.git.sourceforge.net/gitroot/bibletimeofolaf/bibletimeofolaf
 radicke@bibletimeofolaf.git.sourceforge.net's password: 
 Total 0 (delta 0), reused 0 (delta 0)
 To ssh://radicke@bibletimeofolaf.git.sourceforge.net/gitroot/bibletimeofolaf/bibletimeofolaf
  * [new branch]      master -> master

Git teilt uns mit, daß unser "master" als "master" auf "origin" geschoben ("pushed") wurde. Wir können jetzt nochmal einen "clone" erstellen, um zu überprüfen, was die anderen Entwickler bei einem "clone"-Befehl erhalten.

 olaf@gallien-197:~/var/bibletimeofolaf$ cd ..
 olaf@gallien-197:~/var$ mv ./bibletimeofolaf/ ./bibletimeofolaf_backup
 olaf@gallien-197:~/var$ git clone ssh://radicke@bibletimeofolaf.git.sourceforge.net/gitroot/bibletimeofolaf/bibletimeofolaf
 Initialized empty Git repository in /atix/home/olaf/var/bibletimeofolaf/.git/
 radicke@bibletimeofolaf.git.sourceforge.net's password: 
 remote: Counting objects: 31054, done.
 remote: Compressing objects: 100% (4800/4800), done.
 remote: Total 31054 (delta 24155), reused 31054 (delta 24155)
 Receiving objects: 100% (31054/31054), 26.52 MiB | 233 KiB/s, done.
 Resolving deltas: 100% (24155/24155), done.
 Checking out files: 100% (1082/1082), done.
 olaf@gallien-197:~/var$ cd ./bibletimeofolaf
 olaf@gallien-197:~/var/bibletimeofolaf$ ls
 CMakeLists.txt ChangeLog  LICENSE  Makefile  README  README_ATER_GUI.txt  build-debug.sh  build-release.sh  cmake  docs  i18n  pics  src
 olaf@gallien-197:~/var/bibletimeofolaf$ git branch
 * master

Also ist alles nun in bester Ordnung.

Buchempfehlung

"Git- kurz und gut" von Sven Riedel, ISBN-10: 389721914X


KategorieVersionsKontrollSystem

git (zuletzt geändert am 2013-08-22 13:25:59 durch a89-182-216-34)