Bearbeiten, 24. November 2016: Diese Antwort ist anscheinend sehr beliebt, daher füge ich hier eine Notiz hinzu. Wenn Sie ein Tag auf einem zentralen Server ersetzen , kann jeder, der das alte Tag hat - jeder Klon des Repositorys des zentralen Servers, der das Tag bereits hat - sein altes Tag beibehalten . Während dies Ihnen sagt, wie es geht, stellen Sie sicher, dass Sie es tun möchten . Sie müssen alle, die bereits das "falsche" Tag haben, dazu bringen, ihr "falsches Tag" zu löschen und durch das neue "richtige Tag" zu ersetzen.
Das Testen in Git 2.10 / 2.11 zeigt, dass das Beibehalten des alten Tags das Standardverhalten für ausgeführte Clients git fetch
ist und das Aktualisieren das Standardverhalten für ausgeführte Clients ist git fetch --tags
.
(Die ursprüngliche Antwort folgt.)
Wenn Sie nach Push-Tags fragen, wird git push --tags
(zusammen mit allen erforderlichen Commits und anderen Objekten sowie anderen Ref-Updates aus den Push-Einstellungen) eine Aktualisierungsanforderung des Formulars an die Fernbedienung gesendet . (Nun, es werden jedoch viele gesendet: eine davon für jedes Tag.)new-sha1 refs/tags/name
Die Aktualisierungsanforderung wird von der Fernbedienung geändert, um eine old-sha1
(oder erneut eine für jedes Tag) hinzuzufügen , und dann an die Pre-Receive- und / oder Update-Hooks (je nachdem, welche Hooks auf der Fernbedienung vorhanden sind) gesendet. Diese Hooks können entscheiden, ob das Erstellen / Löschen / Aktualisieren des Tags zugelassen oder abgelehnt werden soll.
Der old-sha1
Wert ist die Null-Null "SHA-1", wenn das Tag erstellt wird. Dies new-sha1
ist die Null-SHA-1, wenn das Tag gelöscht wird. Ansonsten sind beide SHA-1-Werte echte, gültige Werte.
Selbst ohne Hooks wird eine Art "eingebauter Hook" ausgeführt: Die Fernbedienung weigert sich, ein Tag zu verschieben, es sei denn, Sie verwenden das Flag "force" (obwohl der "eingebaute Hook" bei beiden immer in Ordnung ist "hinzufügen" und "löschen"). Die Ablehnungsnachricht, die Sie sehen, stammt von diesem integrierten Hook. (Im Übrigen lehnt dieser integrierte Hook auch Verzweigungsaktualisierungen ab, die nicht schnell vorgespult werden.) 1
Aber - hier ist einer der Schlüssel zum Verständnis der Vorgänge - der git push
Schritt hat keine Ahnung, ob die Fernbedienung jetzt über dieses Tag verfügt und wenn ja, welchen SHA-1-Wert sie hat. Es heißt nur "hier ist meine vollständige Liste der Tags zusammen mit ihren SHA-1-Werten". Die Fernbedienung vergleicht die Werte und führt bei Hinzufügungen und / oder Änderungen die Hooks für diese aus. (Für Tags, die gleich sind, macht es überhaupt nichts. Für Tags, die Sie nicht haben, macht es auch nichts!)
Wenn Sie das Tag lokal löschen, push
überträgt Ihr Push das Tag einfach nicht. Die Fernbedienung geht davon aus, dass keine Änderungen vorgenommen werden sollten.
Wenn Sie das Tag lokal löschen und dann auf eine neue Stelle verweisen push
, überträgt Ihr Push das Tag, und die Fernbedienung sieht dies als Tag-Änderung an und lehnt die Änderung ab, es sei denn, es handelt sich um einen Force-Push.
Sie haben also zwei Möglichkeiten:
- einen Kraftstoß machen oder
- Löschen Sie das Tag auf der Fernbedienung.
Letzteres ist über git push
2 möglich , obwohl das Löschen des Tags lokal und push
ing keine Auswirkung hat. Angenommen, der Name der Fernbedienung lautet origin
und das Tag, das gelöscht werden soll, lautet dev
:
git push origin :refs/tags/dev
Dadurch wird die Fernbedienung aufgefordert, das Tag zu löschen. Das Vorhandensein oder Fehlen des Tags dev
in Ihrem lokalen Repository ist irrelevant. Diese Art von push
, mit als Referenz, ist ein reiner Lösch-Push.:remoteref
Die Fernbedienung kann das Löschen von Tags zulassen oder nicht (abhängig von zusätzlichen hinzugefügten Hooks). Wenn das Löschen möglich ist, ist das Tag nicht mehr vorhanden. git push --tags
Wenn ein lokales dev
Tag auf ein Commit- oder kommentiertes Tag-Repo-Objekt verweist, senden Sie Ihr neues dev
Tag. Auf der Fernbedienung dev
wird nun ein neu erstelltes Tag angezeigt, sodass die Fernbedienung wahrscheinlich den Push zulässt (dies hängt wiederum von zusätzlichen hinzugefügten Hooks ab).
Der Force-Push ist einfacher. Wenn Sie sicher sein möchten, dass Sie nichts anderes als das Tag aktualisieren , sagen Sie einfach, git push
dass Sie nur diese eine Referenzspezifikation drücken sollen:
git push --force origin refs/tags/dev:refs/tags/dev
(Hinweis: Sie brauchen nicht, --tags
wenn Sie explizit nur eine Tag-Ref-Spezifikation drücken).
1 Der Grund für diesen integrierten Hook besteht natürlich darin, das Verhalten zu erzwingen, das andere Benutzer desselben Remote-Repos erwarten: Zweige werden nicht zurückgespult und Tags werden nicht verschoben. Wenn Sie einen Force-Push ausführen, sollten Sie die anderen Benutzer darüber informieren, dass Sie dies tun, damit sie dies korrigieren können. Beachten Sie, dass "Tags bewegen sich überhaupt nicht" von Git 1.8.2 neu erzwungen wird. In früheren Versionen konnte das Tag im Festschreibungsdiagramm "vorwärts" verschoben werden, ähnlich wie bei Zweignamen. Siehe die Versionshinweise zu Git 1.8.2 .
2 Es ist trivial, wenn Sie sich auf der Fernbedienung anmelden können. Gehen Sie einfach zum Git-Repository und führen Sie es aus git tag -d dev
. Beachten Sie, dass in beiden Fällen - Löschen des Tags auf der Fernbedienung oder Löschen des Tags - git push
jeder, der auf die Fernbedienung zugreift, feststellt, dass das dev
Tag fehlt. (Sie haben weiterhin ihr eigenes altes Tag, falls sie es bereits haben, und sie können sogar ihr altes Tag wieder nach oben verschieben, bevor Sie das neue verschieben können.)