(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 mit refs/heads/
Namen eines Zweigs beginnt . eine Zeichenfolge, die mit refs/remotes/
Namen eines Fernverfolgungszweigs beginnt ; und eine Zeichenfolge, die mit refs/tags/
Namen eines Tags beginnt . Der Name refs/stash
ist die Stash-Referenz (wie von verwendet git 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
, und CHERRY_PICK_HEAD
insbesondere sind auch alle Namen, die auf bestimmte Commits beziehen (obwohl HEAD
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önnen refs/
. Zum Beispiel können Sie weglassen refs/heads/
oder refs/tags/
auf einen lokalen Zweig oder Tag verweisen - und tatsächlich müssen Sie refs/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 des push
Vorgangs. Sie können auch verwenden git ls-remote
oder git remote show
sie zu sehen, aber fetch
und push
sind die interessanteren Berührungspunkte.
Refspecs
Während fetch
und push
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 Magie fetch
, 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 in refs/heads/
und alles in refs/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
:
$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
$
Diese Refspec weist Git jeden Namen passend zu nehmen refs/heads/*
-ie, jeden Zweig auf dem Remote-und seinen Namen ändern refs/remotes/origin/*
, das heißt, halten Sie den angepassten Teil die gleiche, die Zweignamen (Ändern refs/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 werden origin
. Der Filialname wird zum Remote-Tracking-Filialnamen, wobei der Name der Remote in diesem Fall origin
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 Effekt refs/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 Tag xyzzy
hat und Sie dies nicht tun git fetch origin "refs/tags/*:refs/tags/*"
, werden Sie refs/tags/xyzzy
zu Ihrem Repository hinzugefügt (und verweisen auf dasselbe Commit wie auf der Remote). Wenn Sie +refs/tags/*:refs/tags/*
dann Ihren Tag xyzzy
, wenn Sie eine haben, wird ersetzt durch einen aus origin
. 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ühren git 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, und refs/heads/
und refs/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 Tag xyzzy
und einen Zweig xyzzy
gibt und sie auf unterschiedliche Commits verweisen, dann:
git rev-parse xyzzy
gibt Ihnen die ID, auf die das Tag verweist. Allerdings - und genau das fehlt in gitrevisions
- werden git checkout
Zweigstellennamen bevorzugt, sodass git 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 buchstabieren refs/tags/xyzzy
. (Beachten Sie, dass dies tut Arbeit mit git 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 Tag xyzzy
vorhanden ist. Wenn Sie das Tag auschecken möchten, können Sie es verwenden refs/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.
git checkout A
. was istA
? Wie hast du geschaffenA
?