webentwicklung-frage-antwort-db.com.de

"Tag existiert bereits in der remote" fehler nach dem neu erstellen des git tags

Ich erhalte die folgende Fehlermeldung, nachdem ich die folgenden Schritte ausgeführt habe:

To [email protected]:username/repo-name.git
 ! [rejected]        dev -> dev (already exists)
error: failed to Push some refs to '[email protected]:username/repo-name.git'
hint: Updates were rejected because the tag already exists in the remote.
  1. Erstellt das Repository
  2. Repo auf dem lokalen Rechner geklont.
  3. Änderte die README Datei, übernahm die Änderungen und drückte den Commit.
  4. Erstelltes Tag dev: git tag dev
  5. Pushed-Tags: git Push --tags
  6. Änderte die README Datei, übernahm die Änderungen und drückte den Commit.
  7. Tag dev gelöscht, neu erstellt und Tags gepusht:

    git tag -d dev
    git tag dev
    git Push --tags
    

Warum passiert dies?

Ich bin auf dem Mac. Meine Freunde, die Linux (Ubuntu) verwenden, haben dieses Problem nicht. Ich weiß, dass ich git Push --tags -f Verwenden kann, um die Tag-Aktualisierung zu erzwingen, dies ist jedoch gefährlich (z. B. das versehentliche Überschreiben eines Commits nur im Tag, nicht im Zweig).

129
Luca Boieru

Bearbeiten, 24. November 2016: Diese Antwort ist anscheinend beliebt, daher füge ich hier eine Notiz hinzu. Wenn Sie replace ein Tag auf einem zentralen Server haben, kann jeder, der das old -Tag hat - jeder Klon dieses zentralen Server-Repositorys, der bereits das Tag hat - dies tun Behalte seinen alten Tag. Also, während dies dir sagt, wie es geht, sei dir wirklich sicher, dass du willst es tust. Sie müssen jeden, der bereits das "falsche" Tag hat, dazu bringen, sein "falsches Tag" zu löschen und es durch das neue "richtige Tag" zu ersetzen.

Tests in Git 2.10/2.11 haben gezeigt, dass das Beibehalten des alten Tags das Standardverhalten für Clients ist, auf denen git fetch ausgeführt wird, und das Aktualisieren das Standardverhalten für Clients, auf denen git fetch --tags ausgeführt wird.

(Die ursprüngliche Antwort folgt.)


Wenn Sie nach Push-Tags fragen, sendet git Push --tags (zusammen mit allen erforderlichen Commits und anderen Objekten sowie allen anderen Ref-Updates aus den Push-Einstellungen) eine Aktualisierungsanforderung der Form new-sha1 refs/tags/name an die Fernbedienung. . (Naja, es werden aber viele gesendet: eine davon für jeden Tag.)

Die Aktualisierungsanforderung wird von der Fernbedienung geändert, um ein old-sha1 (oder erneut eines für jedes Tag) hinzuzufügen, und dann an die Hooks vor dem Empfang und/oder der Aktualisierung gesendet ( welche Hooks auch immer auf der Fernbedienung vorhanden sind). Diese Hooks können entscheiden, ob das Erstellen/Löschen/Aktualisieren des Tags zugelassen oder abgelehnt werden soll.

Der Wert old-sha1 ist der Null-SHA-1-Wert, wenn das Tag erstellt wird. Das new-sha1 ist das Null-SHA-1, wenn das Tag gelöscht wird. Ansonsten sind beide SHA-1-Werte echte, gültige Werte.

Selbst ohne Haken gibt es eine Art "eingebauten Haken", der ebenfalls ausgeführt wird: Die Fernbedienung weigert sich, ein Tag zu verschieben, es sei denn, Sie verwenden das Flag "force" (obwohl der "eingebaute Haken" bei beiden immer OK ist.) "hinzufügen" und "löschen"). Die Ablehnungsmeldung, die Sie sehen, stammt von diesem integrierten Hook. (Übrigens lehnt derselbe integrierte Hook auch Zweigaktualisierungen ab, die nicht schnell vorwärts ausgeführt werden.)1

Aber - hier ist einer der Schlüssel, um zu verstehen, was los ist - der Schritt git Push hat keine Ahnung, ob die Fernbedienung dieses Tag jetzt hat und wenn ja, welchen SHA-1-Wert sie hat. Es steht nur "Hier ist meine vollständige Liste der Tags mit ihren SHA-1-Werten". Die Fernbedienung vergleicht die Werte und führt bei Ergänzungen und/oder Änderungen die entsprechenden Hooks aus. (Bei Tags, die gleich sind, geschieht gar nichts. Bei Tags, die Sie nicht haben, geschieht auch nichts!)

Wenn Sie das Tag lokal löschen, dann Push, überträgt Ihr Push das Tag einfach nicht. Die Fernbedienung geht davon aus, dass keine Änderungen vorgenommen werden sollen.

Wenn Sie das Tag lokal löschen, es erstellen und auf eine neue Stelle verweisen, dann Push, überträgt Ihr Push das Tag, und die Fernbedienung betrachtet dies als Tag-Änderung und lehnt die Änderung ab, es sei denn, es handelt sich um einen Force-Push .

Somit haben Sie zwei Möglichkeiten:

  • mache einen Force-Push, oder
  • löschen Sie das Tag auf der Fernbedienung.

Letzteres ist möglich über git Push2 Auch wenn das lokale Löschen des Tags und Pushing keine Auswirkung haben. Angenommen, der Name der Fernbedienung ist Origin, und der Tag, den Sie löschen möchten, ist 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 :remoteref als Referenzangabe ist ein Push zum Löschen.

Die Fernbedienung kann das Löschen von Tags zulassen oder nicht (abhängig von zusätzlichen hinzugefügten Hooks). Wenn es das Löschen zulässt, wird das Tag gelöscht und ein zweites git Push --tags, wenn Sie ein lokales dev Tag haben, das auf ein Commit- oder annotiertes Tag-Repo-Objekt verweist, senden Sie Ihr neues dev Tag. Auf der Fernbedienung ist dev jetzt ein neu erstelltes Tag, sodass die Fernbedienung wahrscheinlich Push zulässt (auch dies hängt von zusätzlichen hinzugefügten Hooks ab).

Der Force-Push ist einfacher. Wenn Sie sicherstellen möchten, dass nichts other als das Tag aktualisiert wird, teilen Sie git Push mit, dass nur diese eine Referenz angegeben werden soll:

git Push --force Origin refs/tags/dev:refs/tags/dev

(Hinweis: Sie benötigen --tags nicht, wenn Sie explizit nur eine Tag-Referenzspezifikation angeben).


1Der Grund für diesen integrierten Hook soll natürlich dazu beitragen, das Verhalten zu erzwingen, das andere Benutzer desselben Remote-Repos erwarten: Verzweigungen werden nicht zurückgespult und Tags werden nicht verschoben. Wenn Sie Push erzwingen, sollten Sie die anderen Benutzer darüber informieren, dass Sie dies tun, damit sie dies korrigieren können. Beachten Sie, dass "Tags überhaupt nicht verschieben" von Git 1.8.2 neu erzwungen wird. Vorgängerversionen ermöglichten es dem Tag, sich im Festschreibungsdiagramm vorwärts zu bewegen, ähnlich wie bei Zweignamen. Siehe Versionshinweise zu Git 1.8.2 .

2Es ist trivial, wenn Sie sich über die Fernbedienung anmelden können. Gehen Sie einfach in das Git-Repository und führen Sie git tag -d dev aus. Beachten Sie, dass in beiden Fällen, wenn Sie das Tag auf der Fernbedienung löschen oder git Push zum Löschen verwenden, der Tag dev für jeden, der auf die Fernbedienung zugreift, nicht vorhanden ist. (Sie werden weiterhin ihr eigenes altes Tag haben, wenn sie es bereits haben, und sie könnten sogar ihr altes Tag sichern, bevor Sie das drücken können ein neues.)

161
torek

Deaktivieren Sie in Mac SourceTree nur das Kontrollkästchen Alle Tags verschieben :

enter image description here

48
itzhar

Es ist ganz einfach , wenn Sie SourceTree verwenden.

enter image description here Grundsätzlich müssen Sie nur das widersprüchliche Tag entfernen und erneut hinzufügen:

  1. Gehe zum Tab Repository -> Tag -> Tag entfernen
  2. Wählen Sie den widersprüchlichen Tag-Namen aus
  3. Häkchen Markierung von allen Fernbedienungen entfernen
  4. Drücken Sie Entfernen
  5. Erstellen Sie ein neues Tag mit demselben Namen für das richtige Commit
  6. Stellen Sie sicher, dass Sie Alle Tags drücken, wenn Sie Ihre Änderungen an die Fernbedienung senden
14
choofie

Wenn Sie UPDATE ein Tag möchten, sagen wir es 1.0.0

  1. git checkout 1.0.0
  2. Nehmen Sie Ihre Änderungen vor
  3. git ci -am 'modify some content'
  4. git tag -f 1.0.0
  5. remote-Tag auf Github löschen: git Push Origin --delete 1.0.0
  6. git Push Origin 1.0.0

ERLEDIGT

12
Kaiyu Lee

Es scheint, dass ich zu spät bei diesem Thema bin und/oder es bereits beantwortet wurde, aber was getan werden könnte, ist: (in meinem Fall hatte ich nur ein Tag lokal, also .. Ich habe das alte Tag gelöscht und es mit einem neuen Tag versehen :

git tag -d v1.0
git tag -a v1.0 -m "My commit message"

Dann:

git Push --tags -f

Damit werden alle Tags auf der Fernbedienung aktualisiert.

Kann gefährlich sein! Verwendung auf eigenes Risiko.

8
André Tzermias

Der Grund, warum Sie abgelehnt erhalten, ist, dass Ihr Tag die Synchronisierung mit der Remote-Version verloren hat. Dies ist das gleiche Verhalten bei Verzweigungen.

synchronisation mit dem Tag von der Fernbedienung über git pull --rebase <repo_url> +refs/tags/<TAG> und nachdem Sie synchronisiert haben, müssen Sie Konflikte verwalten. Wenn Sie ein diftool installiert haben (zB meld) git mergetool meld Verwenden Sie diese Option, um die Fernsteuerung zu synchronisieren und Ihre Änderungen zu speichern.

Der Grund, warum Sie mit dem Flag - rebase ziehen, ist, dass Sie Ihre Arbeit auf die Remote-Arbeit legen möchten, um andere Konflikte zu vermeiden.

Ich verstehe auch nicht, warum Sie das Tag dev löschen und neu erstellen? Tags werden zur Angabe von Softwareversionen oder Meilensteinen verwendet. Beispiel für Git-Tags v0.1dev, v0.0.1alpha, v2.3-cr (Cr - Kandidat Release) und so weiter ..


Eine andere Möglichkeit, dies zu lösen, ist die Ausgabe eines git reflog und gehen Sie zu dem Moment, in dem Sie das Tag dev auf der Fernbedienung gedrückt haben. Kopieren Sie die Commit-ID und git reset --mixed <commmit_id_from_reflog> auf diese Weise wissen Sie, dass Ihr Tag zum Zeitpunkt des Push-Vorgangs mit der Fernbedienung synchronisiert war und keine Konflikte auftreten.

Deaktivieren Sie in Windows SourceTree Push all tags to remotes.

enter image description here

2
Contango