Git-Tags#

Git-Tags sind Referenzen, die auf bestimmte Commits in der Git-Historie verweisen. So können bestimmte Punkte in der Historie für eine bestimmte Version markiert werden, z.B. v3.9.16. Tags sind wie Git-Verzweigungen, die sich nicht ändern, also keine weitere Historie von Commits haben.

git tag TAGNAME

erstellt einen Tag, wobei TAGNAME eine semantische Bezeichnung für den aktuellen Zustand des Git-Repositories ist. Dabei unterscheidet Git zwei verschiedene Arten von Tags: annotierte und leichtgewichtige Tags. Sie unterscheiden sich in der Menge der zugehörigen Metadaten.

Annotierte Tags

Sie speichern nicht nur den TAGNAME, sondern auch zusätzliche Metadaten wie Namen und E-Mail-Adresse derjenigen Person, die den Tag erstellt hat sowie das Datum. Zudem haben annotierte Tags, ähnlich wie Commits Nachrichten. Ihr könnt solche Tags erstellen, z.B. mit git tag -a v3.9.16 -m 'Python 3.9.16'. Anshließend könnt ihr euch diese zusätzlichen Metadaten z.B. anzeigen lassen mit git show v3.9.16.

Leichtgewichtige Tags

Leichtgewichtige Tags können z.B. mit git tag v3.9.16 ohne die Optionen -a, -s oder -m erstellt werden. Sie erstellen eine Tag-Prüfsumme, die im .git/-Verzeichnis eures Repos gespeichert werden.

git tag

listet die Tags eures Repos auf, z.B.:

v0.9.9
v1.0.1
v1.0.2
v1.1
...
git tag -l 'REGEX'

listet nur Tags auf, die zu einem regulären Ausdruck passen.

git tag -a TAGNAME COMMIT-SHA

erstellt einen Tag für einen früheren Commit.

Die vorangegangenen Beispiele erstellen Tags für implizite Commits, die auf HEAD verweisen. Alternativ kann git tag auch die Referenz auf einen bestimmten Commit übergeben werden, die ihr mit log und reflog erhaltet.

Wenn ihr jedoch versucht, ein Tag mit dem gleichen Bezeichner wie ein bestehendes Tag zu erstellen, gibt Git eine Fehlermeldung aus, z.B. Schwerwiegend: Tag 'v3.9.16' existiert bereits. Wenn ihr versucht, einen älteren Commit mit einem bestehenden Tag zu markieren, gibt Git denselben Fehler aus.

Für den Fall, dass ihr einen bestehendes Tag aktualisieren müsst, könnt ihr die Option -f verwenden, z.B.:

$ git tag -af v3.9.16 595f9ccb0c059f2fb5bf13643bfc0cdd5b55a422 -m 'Python 3.9.16'
Tag 'v3.9.16' aktualisiert (war 4f5c5473ea)
git push origin TAGNAME

Das Teilen von Tags ist ähnlich wie der Push von Zweigen: standardmäßig werden mit git push keine Tags freigegeben, sondern sie müssen explizit an git push übergeben werden z.B.:

$ git tag -af v3.9.16 -m 'Python 3.9.16'
$ git push origin v3.9.16
Counting objects: 1, done.
Writing objects: 100% (1/1), 161 bytes, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:python/cpython.git
 * [new tag]         v3.9.16 -> v3.9.16

Um mehrere Tags gleichzeitig zu pushen, übergebt die Option --tags an den Befehl git push. Andere erhalten die Tags bei git clone oder git pull des Repos.

Mit git push --follow-tags könnt ihr mit einem Commit auch gleichzeitig die zugehörigen annotierten Tags teilen.

Bemerkung

--follow-tags funktioniert nur für annotierte Tags, nicht für die leichtgewichtigen Tags.

Wenn ihr für alle zukünftigen Pushes --follow-tags verwenden wollt, könnt ihr dies konfigurieren mit

$ git config --global push.followTags true
git checkout TAGNAME

wechselt in den Zustand des Repository mit diesem Tag und trennt HEAD ab. D.h., dass alle Änderungen, die nun vorgenommen werden, das Tag nicht aktualisieren, sondern in einem losgelösten Commit landen, der nicht Teil eines Zweiges sein kann und nur direkt über den SHA-Hash des Commits erreichbar sein wird. Daher wird meist ein neuer Zweig erstellt, wenn solche Änderungen vorgenommen werden sollen, z.B. mit git checkout -b v3.9.17 v3.9.16.

git tag -d TAGNAME

löscht einen Tag, z.B.:

$ git tag -d v3.9.16
$ git push origin --delete v3.9.16