-
1. Los geht's
- 1.1 Wozu Versionskontrolle?
- 1.2 Die Geschichte von Git
- 1.3 Git Grundlagen
- 1.4 Git installieren
- 1.5 Git konfigurieren
- 1.6 Hilfe finden
- 1.7 Zusammenfassung
-
2. Git Grundlagen
-
3. Git Branching
- 3.1 Was ist ein Branch?
- 3.2 Einfaches Branching und Merging
- 3.3 Branch Management
- 3.4 Branching Workflows
- 3.5 Externe Branches
- 3.6 Rebasing
- 3.7 Zusammenfassung
-
4. Git auf dem Server
- 4.1 Die Protokolle
- 4.2 Git auf einen Server bekommen
- 4.3 Generiere deinen öffentlichen SSH-Schlüssel
- 4.4 Einrichten des Servers
- 4.5 Öffentlicher Zugang
- 4.6 GitWeb
- 4.7 Gitosis
- 4.8 Gitolite
- 4.9 Git Daemon
- 4.10 Git Hosting
- 4.11 Einrichten eines Benutzeraccounts
- 4.12 Zusammenfassung
-
5. Distribuierte Arbeit mit Git (xxx)
-
6. Git Tools
- 6.1 Revision Auswahl
- 6.2 Interaktives Stagen
- 6.3 Stashing
- 6.4 Änderungshistorie verändern
- 6.5 Mit Hilfe von Git debuggen
- 6.6 Submodule
- 6.7 Subtree Merging
- 6.8 Zusammenfassung
-
7. Git individuell einrichten
-
8. Git und andere Versionsverwaltungen
- 8.1 Git und Subversion
- 8.2 Zu Git umziehen
- 8.3 Zusammenfassung
-
9. Git Internas
- 9.1 Plumbing und Porcelain
- 9.2 Git Objekte
- 9.3 Git Referenzen
- 9.4 Pack-Dateien
- 9.5 Die Refspec
- 9.6 Transfer Protokolle
- 9.7 Wartung und Datenwiederherstellung
- 9.8 Zusammenfassung
9.5 Git Internas - Die Refspec
Die Refspec
In diesem Buch haben wir bisher einfache Mappings von externen Branches auf lokale Referenzen verwendet. Sie können aber auch durchaus komplex sein. Nehmen wir an, du hast ein externes Repository wie folgt definiert:
$ git remote add origin git@github.com:schacon/simplegit-progit.git
Das fügt eine Sektion in deine .git/config Datei hinzu, die deinen lokalen Namen des externen Repositories (origin), dessen URL und die Refspec spezifiziert, mit der neue Daten heruntergeladen werden.
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/*:refs/remotes/origin/*
Das Format der Refspec besteht aus einem optionalen + gefolgt von <quelle>:<ziel>, wobei <quelle> ein Pattern für Referenzen auf der Remote Seite ist, und <ziel> angibt, wohin diese Referenzen lokal geschrieben werden. Das + weist Git an, die Referenz zu mergen, wenn sie nicht mit einem fast-forward aktualisiert werden kann.
Der Standard, der von git remote add automatisch eingerichtet wird, besteht darin, daß Git austomatisch alle Referenzen unter refs/heads/ vom Server holt und sie lokal nach refs/remotes/origin speichert. D.h., wenn es auf dem Server einen master Branch gibt, kannst du auf das Log dieses Branches wie folgt zugreifen:
$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master
Diese Varianten sind allesamt äquivalent, weil Git sie jeweils zu refs/remotes/origin/master vervollständigt.
Wenn du statt dessen willst, daß Git jeweils nur den master Branch herunterlädt und andere Branches auf dem Server ignoriert, kannst du die fetch Zeile wie folgt ändern:
fetch = +refs/heads/master:refs/remotes/origin/master
Dies ist allerdings lediglich der Default Refspec Wert und du kannst ihn auf der Kommandozeile jederzeit überschreiben. Z.B. um nur master branch vom Server lokal als origin/mymaster zu speichern, kannst du folgendes ausführen:
$ git fetch origin master:refs/remotes/origin/mymaster
Du kannst auch mehrere Refspecs gleichzeitig spezifizieren. Z.B.:
$ git fetch origin master:refs/remotes/origin/mymaster \
topic:refs/remotes/origin/topic
From git@github.com:schacon/simplegit
! [rejected] master -> origin/mymaster (non fast forward)
* [new branch] topic -> origin/topic
I diesem Fall wurde ein Pull zurückgewiesen (xxx ist das nicht nur ein fetch? xxx), weil der Branch nicht mit einem simplen fast-forward aktualisiert werden konnte. Du kannst einen Merge erzwingen, indem du der Refspec ein + voranstellst.
Du kannst außerdem natürlich auch mehrere Refspecs in deiner Konfiguration spezifizieren. Wenn du z.B. immer die master und experiment Branches holen willst, fügst du die folgenden Zeilen hinzu:
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/experiment:refs/remotes/origin/experiment
Du kannst keine partiellen Glob Patterns verwenden, d.h. folgendes wäre ungültig:
fetch = +refs/heads/qa*:refs/remotes/origin/qa*
Allerdings kannst du Namensräume verwenden, um etwas ähnliches zu erreichen. Nehmen wir an, du hast ein QA Team, das regelmäßig verschiedene Branches pusht, und du willst nun den master Branch und sämtliche Branches des QA Teams, aber keine anderen Branches haben. Dann kannst du eine Config Sektion wie die folgende verwenden:
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*
In einem großen Team mit einem komplexen Workflow, in dem ein QA Team, Entwickler und ein Integrations Team jeweils eigene Branches pushen, kann man auf diese Weise Branches einfach in Namensräume einteilen.
Refspecs pushen
Wie aber legt das QA Team die Branches im qa/ Namensraum ab? Das geht, indem man mit einer Refspec pusht.
Wenn das QA Team seinen master Branch in einem externen Repository als qa/master speichern will, kann es das wie folgt tun:
$ git push origin master:refs/heads/qa/master
Um Git so zu konfigurieren, daß diese Refspec jedes mal automatisch für git push origin verwendet wird, kann man den push Wert in der Config Datei setzen:
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/master:refs/heads/qa/master
Auf diese Weise wird git push origin den lokalen Branch master als qa/master auf dem origin Server speichern.
Referenzen löschen
Man kann Refspecs außerdem verwenden, um Referenzen aus einem externen Repository zu löschen:
$ git push origin :topic
Das Refspec Format ist <quelle>:<ziel>. Wenn man den <ziel> Teil wegläßt, dann heißt das im obigen Beispiel, daß man den topic Branch auf dem origin Server auf "nichts" setzt, d.h. also löscht.