Git
Chapters ▾ 2nd Edition

2.6 Git Grundlagen - Taggen

Taggen

Wie die meisten VCSs hat Git die Möglichkeit, bestimmte Punkte in der Historie eines Repositorys als wichtig zu markieren. Normalerweise verwenden Leute diese Funktionalität, um Releases zu markieren (v1.0, v2.0 usw). In diesem Abschnitt erfährst du, wie bestehende Tags aufgelistet, Tags erstellt und gelöscht werden können sowie was die unterschiedlichen Tag-Typen sind.

Deine Tags auflisten

Die Auflistung der vorhandenen Tags in Git ist unkompliziert. Gib einfach git tag (mit optionalem -l oder --list) ein:

$ git tag
v1.0
v2.0

Dieser Befehl listet die Tags in alphabetischer Reihenfolge auf. Die Reihenfolge, in der sie angezeigt werden, hat keine wirkliche Bedeutung.

Du kannst auch nach Tags suchen, die einer bestimmten Zeichenfolge entsprechen. Das Git-Source-Repo zum Beispiel enthält mehr als 500 Tags. Wenn du nur daran interessiert bist, dir die 1.8.5-Serie anzusehen, kannst du Folgendes ausführen:

$ git tag -l "v1.8.5*"
v1.8.5
v1.8.5-rc0
v1.8.5-rc1
v1.8.5-rc2
v1.8.5-rc3
v1.8.5.1
v1.8.5.2
v1.8.5.3
v1.8.5.4
v1.8.5.5
Anmerkung
Das Auflisten von Tag-Wildcards erfordert die Option -l oder --list

Wenn du lediglich die gesamte Liste der Tags wünschst, geht die Ausführung des Befehls git tag implizit davon aus, dass du eine Auflistung haben willst und gibt sie aus; die Verwendung von -l oder --list ist in diesem Fall optional.

Wenn du jedoch ein Platzhaltermuster angibst, das mit den Tag-Namen übereinstimmt, ist die Verwendung von -l oder --list obligatorisch.

Erstellen von Tags

Git unterstützt zwei Arten von Tags: lightweight (d.h. nicht-annotiert) und annotated.

Ein nicht-annotiertes Tag ist sehr ähnlich eines Branches, der sich nicht ändert – es ist nur ein Zeiger auf einen bestimmten Commit.

Annotierte Tags werden dagegen als vollständige Objekte in der Git-Datenbank gespeichert. Sie werden mit einer Prüfsumme versehen, enthalten den Tagger-Namen, die E-Mail-Adresse und das Datum, haben eine Tagging-Nachricht und können mit GNU Privacy Guard (GPG) signiert und überprüft werden. Es wird allgemein empfohlen annotierte Tags zu erstellen, damit all diese Informationen gespeichert werden; aber wenn du ein temporäres Tag wünschst oder aus irgendwelchen Gründen die anderen Informationen nicht speichern willst, sind auch nicht-annotierte Tags möglich.

Annotated Tags

Das Erstellen eines annotierten Tags in Git ist einfach. Der einfachste Weg ist die Eingabe von -a, beim Ausführen des tag Befehls:

$ git tag -a v1.4 -m "my version 1.4"
$ git tag
v0.1
v1.3
v1.4

Ein -m spezifiziert eine Tagging-Nachricht, die mit dem Tag gespeichert wird. Wenn du keine Nachricht für ein annotierten Tag angibst, startet Git deinen Editor, damit du eine Nachricht eingeben kannst.

Du kannst die Tag-Daten zusammen mit dem getaggten Commit sehen, indem du den Befehl git show verwendest:

$ git show v1.4
tag v1.4
Tagger: Ben Straub <ben@straub.cc>
Date:   Sat May 3 20:19:12 2014 -0700

my version 1.4

commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

Es werden die Tagger-Informationen, das Datum an dem der Commit getaggt wurde, und die Annotationsnachricht angezeigt, gefolgt von den Commit-Informationen.

Lightweight Tags

Eine weitere Möglichkeit, Commits zu markieren, ist ein leichtgewichtiger, nicht-annotierter Tag. Das ist im Grunde genommen die in einer Datei gespeicherte Commit-Prüfsumme – es werden keine weiteren Informationen gespeichert. Um einen leichtgewichtigen Tag zu erstellen, gib keine der Optionen -a, -s oder -m an, sondern nur einen Tag-Namen:

$ git tag v1.4-lw
$ git tag
v0.1
v1.3
v1.4
v1.4-lw
v1.5

Wenn du diesmal git show auf dem Tag ausführst, siehst du keine zusätzlichen Tag-Informationen. Der Befehl zeigt nur den Commit an:

$ git show v1.4-lw
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

Nachträgliches Tagging

Du kannst auch ältere Commits markieren. Angenommen, dein Commit-Verlauf sieht so aus:

$ git log --pretty=oneline
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 Create write support
0d52aaab4479697da7686c15f77a3d64d9165190 One more thing
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc Add commit function
4682c3261057305bdd616e23b64b0857d832627b Add todo file
166ae0c4d3f420721acbb115cc33848dfcc2121a Create write support
9fceb02d0ae598e95dc970b74767f19372d61af8 Update rakefile
964f16d36dfccde844893cac5b347e7b3d44abbc Commit the todo
8a5cbc430f1a9c3d00faaeffd07798508422908a Update readme

Nehmen wir an, du hast vergessen, das Projekt mit v1.2 beim Commit von „Update rakefile“ zu taggen. Du kannst ihn nachträglich hinzufügen. Um diesen Commit zu markieren, gib am Ende des Befehls die Commit-Prüfsumme (oder einen Teil davon) an:

$ git tag -a v1.2 9fceb02

Du siehst, dass du den Commit getaggt hast:

$ git tag
v0.1
v1.2
v1.3
v1.4
v1.4-lw
v1.5

$ git show v1.2
tag v1.2
Tagger: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Feb 9 15:32:16 2009 -0800

version 1.2
commit 9fceb02d0ae598e95dc970b74767f19372d61af8
Author: Magnus Chacon <mchacon@gee-mail.com>
Date:   Sun Apr 27 20:43:35 2008 -0700

    Update rakefile
...

Tags teilen

Normalerweise überträgt der Befehl git push keine Tags an den Remote-Server. Du musst Tags explizit auf einen Server verschieben, nachdem du sie erstellt hast. Dieser Prozess funktioniert genauso wie das Teilen von Remote-Branches – Du musst dazu git push origin <tagname> ausführen.

$ git push origin v1.5
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (14/14), 2.05 KiB | 0 bytes/s, done.
Total 14 (delta 3), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
 * [new tag]         v1.5 -> v1.5

Wenn du viele Tags hast, die du auf einmal pushen willst, kannst du auch die Option --tags mit dem Befehl git push verwenden. Dadurch werden alle deine Tags auf den Remote-Server übertragen, die sich noch nicht auf dem Server befinden.

$ git push origin --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 160 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
 * [new tag]         v1.4 -> v1.4
 * [new tag]         v1.4-lw -> v1.4-lw

Wenn jetzt jemand anderes aus deinem Repository klont oder pullt, erhält er auch alle deine Tags.

Anmerkung
git push pusht beide Arten von Tags

git push <remote> --tags wird sowohl Lightweight- als auch Annotated-Tags pushen. Es gibt zur Zeit keine Möglichkeit, nur Lightweight-Tags zu pushen, aber wenn du git push <remote> --follow-tags verwendest, werden nur annotierte Tags an den Remote gepusht.

Tags löschen

Um einen Tag aus dem lokalen Repository zu löschen, verwende git tag -d <tagname>. Wir könnten beispielsweise den leichtgewichtigen Tag wie folgt entfernen:

$ git tag -d v1.4-lw
Deleted tag 'v1.4-lw' (was e7d5add)

Beachte, dass dadurch der Tag nicht von Remote-Servern entfernt wird. Es gibt zwei gängige Varianten, um ein Tag von einem remote Server zu löschen.

Die erste Möglichkeit ist git push <remote> :refs/tags/<tagname>:

$ git push origin :refs/tags/v1.4-lw
To /git@github.com:schacon/simplegit.git
 - [deleted]         v1.4-lw

Zur Erklärung des obigen Befehls: Vor dem Doppelpunkt ist nichts und somit als Nullwert zu lesen. Darauf wird der Remote-Tag-Name gepusht, wodurch dieser gelöscht wird.

Der zweite, intuitivere Weg, ein Remote-Tag zu löschen, ist mit:

$ git push origin --delete <tagname>

Tags auschecken

Wenn du die Dateiversion anzeigen möchtest, auf die ein bestimmter Tag zeigt, kannst du git checkout auf dieses Tag durchführen. Dies versetzt dein Repository in den Zustand „detached HEAD“ (dt. losgelöst), was einige negative Nebenwirkungen hat:

$ git checkout v2.0.0
Note: switching to 'v2.0.0'.

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 -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 99ada87... Merge pull request #89 from schacon/appendix-final

$ git checkout v2.0-beta-0.1
Previous HEAD position was 99ada87... Merge pull request #89 from schacon/appendix-final
HEAD is now at df3f601... Add atlas.json and cover image

Wenn du im Zustand „detached HEAD“ Änderungen wornimmst und dann einen Commit erstellst, bleibt der Tag gleich, aber dein neuer Commit gehört zu keinem Branch und ist unzugänglich, außer mit dem genauen Commit-Hash. Wenn du also Änderungen vornehmen musst – z.B. wenn du einen Fehler in einer älteren Version behebst – wirst du normalerweise einen Branch erstellen:

$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'

Wenn du das tust und einen Commit erstellst, wird sich dein Branch version2 leicht von deinem Tag v2.0.0 unterscheiden, da er mit deinen neuen Änderungen fortschreitet, sei also vorsichtig.

scroll-to-top