Beginnen wir mit der Erklärung, was ein Tag in Git ist
Ein Tag wird verwendet, um ein bestimmtes Commit im Verlauf zu kennzeichnen und zu markieren .
Es wird normalerweise zum Markieren von Freigabepunkten verwendet (z. B. v1.0 usw.).
Obwohl ein Tag möglicherweise einem Zweig ähnelt , ändert sich ein Tag nicht . Es verweist direkt auf ein bestimmtes Commit in der Historie.
Sie können die Tags nicht auschecken, wenn sie sich nicht lokal in Ihrem Repository befinden. Zuerst müssen Sie fetch
die Tags in Ihrem lokalen Repository speichern.
Stellen Sie zunächst sicher, dass das Tag lokal vorhanden ist
# --all will fetch all the remotes.
# --tags will fetch all tags as well
$ git fetch --all --tags --prune
Überprüfen Sie dann das Tag, indem Sie es ausführen
$ git checkout tags/<tag_name> -b <branch_name>
Anstatt origin
das tags/
Präfix zu verwenden.
In diesem Beispiel haben Sie 2 Tags, Version 1.0 und Version 1.1. Sie können sie mit einer der folgenden Optionen überprüfen:
$ git checkout A ...
$ git checkout version 1.0 ...
$ git checkout tags/version 1.0 ...
Alle oben genannten Schritte machen dasselbe, da das Tag nur ein Zeiger auf ein bestimmtes Commit ist.
Herkunft: https://backlog.com/git-tutorial/img/post/stepup/capture_stepup4_1_1.png
Wie sehe ich die Liste aller Tags?
# list all tags
$ git tag
# list all tags with given pattern ex: v-
$ git tag --list 'v-*'
Wie erstelle ich Tags?
Es gibt zwei Möglichkeiten, ein Tag zu erstellen:
# lightweight tag
$ git tag
# annotated tag
$ git tag -a
Der Unterschied zwischen den beiden besteht darin, dass Sie beim Erstellen eines mit Anmerkungen versehenen Tags Metadaten hinzufügen können, wie Sie sie in einem Git-Commit haben:
Name, E-Mail, Datum, Kommentar und Signatur
Wie lösche ich Tags?
# delete any (local) given tag
$ git tag -d <tag name>
# Delete a tag from the server with push tags
$ git push --delete origin <tag name>
Wie klone ich ein bestimmtes Tag?
Um den Inhalt eines bestimmten Tags abzurufen, können Sie den checkout
Befehl verwenden. Wie oben erläutert, sind Tags wie alle anderen Commits, sodass wir sie verwenden können checkout
und statt SHA-1 einfach durch den Tag-Namen zu ersetzen
Option 1:
# Update the local git repo with the latest tags from all remotes
$ git fetch --all
# checkout the specific tag
$ git checkout tags/<tag> -b <branch>
Option 2:
Verwenden des Befehls clone
Da git das flache Klonen durch Hinzufügen des --branch
Befehls zum Klon unterstützt, können wir den Tag-Namen anstelle des Verzweigungsnamens verwenden. Git weiß, wie man den gegebenen SHA-1 in das entsprechende Commit "übersetzt"
# Clone a specific tag name using git clone
$ git clone <url> --branch=<tag_name>
Git-Klon --branch =
--branch
kann auch Tags nehmen und den HEAD bei diesem Commit im resultierenden Repository trennen.
Wie man Tags pusht?
git push --tags
So pushen Sie alle Tags:
# Push all tags
$ git push --tags
Verwenden Sie das, refs/tags
anstatt nur das anzugeben <tagname>
.
Warum? - Es wird empfohlen, diese zu verwenden, refs/tags
da Tags manchmal denselben Namen wie Ihre Zweige haben können und durch einfaches Git-Push der Zweig anstelle des Tags verschoben wird
Verwenden Sie Folgendes, um mit Anmerkungen versehene Tags und aktuelle Verlaufsketten-Tags zu verschieben:
git push --follow-tags
Dieses Flag --follow-tags
überträgt beide Commits und nur Tags , die beide sind:
- Kommentierte Tags (damit Sie lokale / temporäre Build-Tags überspringen können)
- Erreichbare Tags (ein Vorfahr) aus dem aktuellen Zweig (im Verlauf)
Ab Git 2.4 können Sie es mithilfe der Konfiguration festlegen
$ git config --global push.followTags true
Spickzettel:
git checkout A
. was istA
? Wie hast du geschaffenA
?A
ist ein Commit-Hashgit checkout tags/<tag_name> -b <branch_name>
das erfordert-b <branch_name>
.git checkout tags/<tag_name>
gab mir einen losgelösten Kopf. Gemäß diesem Artikel über abgetrennten Kopf vermeiden Sie einen abgetrennten Kopf, indem Sie vorübergehend einen Zweig erstellen und löschen. Dies ist ein ziemlich fremder Arbeitsablauf. Natürlich muss ich mich als Git-Benutzer daran gewöhnen, Zweige zum Spaß und zum Profit zu erstellen und zu löschen.(Das Schreiben dieser Antwort hat eine Weile gedauert , und die Antwort von codeWizard ist in Ziel und Wesen korrekt, aber nicht vollständig, daher werde ich sie trotzdem veröffentlichen.)
Es gibt kein "Remote-Git-Tag". Es gibt nur "Tags". Ich weise darauf hin, dass dies alles nicht pedantisch ist 1, aber weil dies bei gelegentlichen Git-Benutzern sehr verwirrend ist und die Git-Dokumentation für Anfänger nicht sehr hilfreich ist 2 . (Es ist nicht klar, ob die Verwirrung auf eine schlechte Dokumentation zurückzuführen ist oder ob die schlechte Dokumentation darauf zurückzuführen ist, dass dies von Natur aus etwas verwirrend ist, oder was.)
Es gibt "Remote-Zweige", besser gesagt "Remote-Tracking-Zweige", aber es ist erwähnenswert, dass es sich tatsächlich um lokale Entitäten handelt. Es gibt jedoch keine Remote-Tags (es sei denn, Sie erfinden sie (neu)). Es gibt nur lokale Tags, daher müssen Sie das Tag lokal abrufen, um es verwenden zu können.
Die allgemeine Form für Namen für bestimmte Commits, die Git als Referenzen bezeichnet, ist eine beliebige Zeichenfolge, die mit beginnt
refs/
. Eine Zeichenfolge, die mitrefs/heads/
Namen eines Zweigs beginnt . eine Zeichenfolge, die mitrefs/remotes/
Namen eines Fernverfolgungszweigs beginnt ; und eine Zeichenfolge, die mitrefs/tags/
Namen eines Tags beginnt . Der Namerefs/stash
ist die Stash-Referenz (wie von verwendetgit stash
; beachten Sie das Fehlen eines abschließenden Schrägstrichs).Es gibt einige ungewöhnliche Spezialfall - Namen , die mit nicht beginnen
refs/
:HEAD
,ORIG_HEAD
,MERGE_HEAD
, undCHERRY_PICK_HEAD
insbesondere sind auch alle Namen, die auf bestimmte Commits beziehen (obwohlHEAD
normalerweise den Namen eines Zweigs enthält, dh enthält ). Im Allgemeinen beginnen Referenzen jedoch mit .ref: refs/heads/branch
refs/
Eine Sache, die Git macht, um dies verwirrend zu machen, ist, dass Sie das
refs/
und oft das Wort danach weglassen könnenrefs/
. Zum Beispiel können Sie weglassenrefs/heads/
oderrefs/tags/
auf einen lokalen Zweig oder Tag verweisen - und tatsächlich müssen Sierefs/heads/
beim Auschecken eines lokalen Zweigs weglassen ! Sie können dies tun, wenn das Ergebnis eindeutig ist oder - wie wir gerade bemerkt haben - wenn Sie es tun müssen (für ).git checkout branch
Es ist richtig, dass Referenzen nicht nur in Ihrem eigenen Repository vorhanden sind, sondern auch in Remote-Repositorys. Mit Git können Sie jedoch nur zu bestimmten Zeiten auf die Referenzen eines Remote-Repositorys zugreifen: nämlich während
fetch
und während despush
Vorgangs. Sie können auch verwendengit ls-remote
odergit remote show
sie zu sehen, aberfetch
undpush
sind die interessanteren Berührungspunkte.Refspecs
Während
fetch
undpush
verwendet Git Zeichenfolgen, die refspecs aufruft , um Referenzen zwischen dem lokalen und dem Remote-Repository zu übertragen. Daher können zu diesen Zeiten und über Refspecs zwei Git-Repositorys miteinander synchronisiert werden. Sobald Ihre Namen synchronisiert sind, können Sie denselben Namen verwenden, den jemand mit der Fernbedienung verwendet. Hier gibt es jedoch eine besondere Magiefetch
, die sowohl Zweig- als auch Tag-Namen betrifft.Sie sollten sich vorstellen
git fetch
, Ihren Git anzuweisen, einen anderen Git - die "Fernbedienung" - aufzurufen (oder eine SMS zu senden) und mit ihm zu sprechen. Zu Beginn dieses Gesprächs listet die Fernbedienung alle ihre Referenzen auf: alles inrefs/heads/
und alles inrefs/tags/
, zusammen mit allen anderen Referenzen, die sie hat. Ihr Git durchsucht diese und benennt (basierend auf der üblichen Abrufreferenz) ihre Zweige um.Werfen wir einen Blick auf die normale Referenz für die Fernbedienung mit dem Namen
origin
:Diese Refspec weist Git jeden Namen passend zu nehmen
refs/heads/*
-ie, jeden Zweig auf dem Remote-und seinen Namen ändernrefs/remotes/origin/*
, das heißt, halten Sie den angepassten Teil die gleiche, die Zweignamen (Ändernrefs/heads/
) zu einem Remote-Tracking - Zweignamen (refs/remotes/
speziell ,refs/remotes/origin/
).Es ist durch diese Refspec , dass
origin
‚s Filialen für Fern Ihre Fernverfolgung Zweige werdenorigin
. Der Filialname wird zum Remote-Tracking-Filialnamen, wobei der Name der Remote in diesem Fallorigin
enthalten ist. Das Pluszeichen+
an der Vorderseite der Referenzspezifikation setzt das "Force" -Flag, dh Ihr Fernverfolgungszweig wird aktualisiert, um mit dem Zweigstellennamen der Fernbedienung übereinzustimmen, unabhängig davon, was erforderlich ist, um die Übereinstimmung herzustellen. (Ohne das+
sind Verzweigungsaktualisierungen auf Änderungen beim "schnellen Vorlauf" beschränkt, und Tag-Aktualisierungen werden seit Git-Version 1.8.2 oder so einfach ignoriert - zuvor wurden dieselben Regeln für den schnellen Vorlauf angewendet.)Stichworte
Aber was ist mit Tags? Es gibt keine Referenz für sie - zumindest nicht standardmäßig. Sie können eine festlegen. In diesem Fall liegt die Form der Referenz bei Ihnen. oder du kannst rennen
git fetch --tags
. Die Verwendung--tags
hat den Effektrefs/tags/*:refs/tags/*
, dass die Refspec hinzugefügt wird, dh alle Tags werden übertragen (aktualisiert Ihr Tag jedoch nicht, wenn Sie bereits ein Tag mit diesem Namen haben, unabhängig davon, was auf dem Tag der Fernbedienung steht.Bearbeiten, Januar 2017: ab Git 2.10 Tests haben gezeigt, dass--tags
Ihre Tags zwangsweise von den Tags der Fernbedienung aktualisiert werden, als ob die Referenzspezifikation gelesen hätte+refs/tags/*:refs/tags/*
(dies kann ein Unterschied im Verhalten gegenüber einer früheren Version von Git sein).Beachten Sie, dass hier keine Umbenennung erfolgt: Wenn remote
origin
ein Tagxyzzy
hat und Sie dies nicht tungit fetch origin "refs/tags/*:refs/tags/*"
, werden Sierefs/tags/xyzzy
zu Ihrem Repository hinzugefügt (und verweisen auf dasselbe Commit wie auf der Remote). Wenn Sie+refs/tags/*:refs/tags/*
dann Ihren Tagxyzzy
, wenn Sie eine haben, wird ersetzt durch einen ausorigin
. Das heißt, das+
Force-Flag in einer Referenz bedeutet "Ersetzen Sie den Wert meiner Referenz durch den Wert, den mein Git von seinem Git erhält".Automagische Tags beim Abrufen
Aus historischen Gründen 3 ergreift 3, wenn Sie weder die
--tags
Option noch die--no-tags
Option verwenden,git fetch
besondere Maßnahmen. Denken Sie daran, dass wir oben gesagt haben, dass die Fernbedienung zunächst Ihrem lokalen Git alle Referenzen anzeigt , unabhängig davon, ob Ihr lokaler Git sie sehen möchte oder nicht. 4 Ihr Git nimmt alle Tags zur Kenntnis, die es an dieser Stelle sieht.Wenn dann das Herunterladen von Commit-Objekten beginnt, die für das Abrufen benötigt werden, fügt git dieses Tag - oder diese Tags, wenn mehrere Tags diese ID haben - hinzu, wenn eines dieser Commits dieselbe ID wie eines dieser Tags hat Ihr Repository.Bearbeiten, Januar 2017: zeigt die Prüfung , dass das Verhalten in Git 2.10 ist nun: Wenn sie Git einen Tag mit dem Namen liefert T , und Sie haben keinen Tag mit dem Namen T , und die Commit - ID mit zugehörigem T ist ein Vorfahre eines ihres Zweiges Wenn Sie
git fetch
prüfen, fügt Ihr Git Ihren Tags mit oder ohne T hinzu--tags
. Durch--tags
das Hinzufügen erhält Ihr Git alle Tags und erzwingt auch die Aktualisierung.Endeffekt
Möglicherweise müssen Sie verwenden
git fetch --tags
, um ihre Tags zu erhalten. Wenn ihre Tag-Namen mit Ihren vorhandenen Tag-Namen in Konflikt stehen, müssen Sie möglicherweise (abhängig von der Git-Version) sogar einige Ihrer Tags löschen (oder umbenennen) und dann ausführengit fetch --tags
, um ihre Tags abzurufen. Da Tags im Gegensatz zu Remote-Zweigen nicht automatisch umbenannt werden, müssen Ihre Tag-Namen mit ihren Tag-Namen übereinstimmen. Aus diesem Grund können Probleme mit Konflikten auftreten.In den meisten normalen Fällen erledigt ein einfacher
git fetch
Benutzer die Aufgabe, indem er seine Commits und die passenden Tags überträgt. Da sie - wer auch immer sie sind - Commits zum Zeitpunkt der Veröffentlichung dieser Commits markieren, werden Sie mit ihren Tags Schritt halten. Wenn Sie keine eigenen Tags erstellen oder deren Repository und andere Repositorys nicht mischen (über mehrere Fernbedienungen), treten auch keine Kollisionen mit Tag-Namen auf, sodass Sie sich nicht um das Löschen oder Umbenennen von Tags kümmern müssen erhalten ihre Tags.Wenn Sie qualifizierte Namen benötigen
Ich erwähnte oben , dass man weglassen kann
refs/
fast immer, undrefs/heads/
undrefs/tags/
und so weiter die meiste Zeit. Aber wann kannst du nicht ?Die vollständige (oder fast vollständige) Antwort finden Sie in der
gitrevisions
Dokumentation . Git löst einen Namen in eine Commit-ID unter Verwendung der im Link angegebenen sechsstufigen Sequenz auf. Seltsamerweise überschreiben Tags Zweige: Wenn es ein Tagxyzzy
und einen Zweigxyzzy
gibt und sie auf unterschiedliche Commits verweisen, dann:gibt Ihnen die ID, auf die das Tag verweist. Allerdings - und genau das fehlt in
gitrevisions
- werdengit checkout
Zweigstellennamen bevorzugt, sodassgit checkout xyzzy
Sie in den Zweig gelangen und das Tag nicht berücksichtigen.Bei Unklarheiten können Sie den Referenznamen fast immer mit seinem vollständigen Namen
refs/heads/xyzzy
oder buchstabierenrefs/tags/xyzzy
. (Beachten Sie, dass dies tut Arbeit mitgit checkout
, aber auf eine vielleicht unerwartete Weise:git checkout refs/heads/xyzzy
führt eine freistehende-HEAD Kasse eher als ein Zweig der Kasse diesem Grund sollten Sie nur zu Kenntnis haben , die.git checkout
Den Kurznamen als Zweignamen zuerst verwenden: Das ist , wie Sie Überprüfen Sie den Zweig,xyzzy
auch wenn das Tagxyzzy
vorhanden ist. Wenn Sie das Tag auschecken möchten, können Sie es verwendenrefs/tags/xyzzy
.)Da (als
gitrevisions
Notizen) Git es versucht , können Sie auch einfach schreiben , um das mit Tags versehene Commit zu identifizieren . (Wenn es jemandem gelungen ist, eine gültige Referenz mit dem Namen in zu schreiben , wird dies wie folgt aufgelöst . Normalerweise sollten jedoch nur die verschiedenen Namen in sein .)refs/name
tags/xyzzy
xyzzy
xyzzy
$GIT_DIR
$GIT_DIR/xyzzy
*HEAD
$GIT_DIR
1 Okay, okay, "nicht nur um pedantisch zu sein". :-)
2 Einige würden "sehr nicht hilfreich" sagen, und ich würde eher zustimmen.
3 Grundsätzlich
git fetch
und das gesamte Konzept von Fernbedienungen und Refspecs war eine etwas späte Ergänzung zu Git, die um die Zeit von Git 1.5 herum stattfand. Zuvor gab es nur einige Ad-hoc-Sonderfälle, und das Abrufen von Tags war einer davon, sodass es über einen speziellen Code großväterlich behandelt wurde.4 Wenn es hilft, stellen Sie sich das entfernte Git als Blinker im Slang vor.
quelle
git fetch
Ruft nur die Tags der Fernbedienung ab, wenn das--tags
Argument vorliegt.--tags
,--no-tags
und das Standard ist eigentlich ziemlich schwierig. Standardmäßig werden Tags eingefügt, die nicht in den von Ihnen eingebrachten Commits enthalten sind. (Siehe die Bearbeitung vom Januar 2017.) Aber auch hier gibt es Pannen, und das moderne Git hat seine --tags / --no-tags-Bearbeitungscode wurde erneut überarbeitet, was wahrscheinlich zu noch spezielleren Eckfällen führen wird.Um ein Git-Tag auszuchecken, führen Sie den folgenden Befehl aus
zB wie unten erwähnt.
Verwenden Sie den Befehl, um alle Tags abzurufen
quelle
Um den spezifischen Tag-Code zu erhalten, versuchen Sie, einen neuen Zweig zu erstellen. Fügen Sie den Tag-Code hinzu. Ich habe es auf Befehl getan:
$git checkout -b newBranchName tagName
quelle