warum git ermöglichen Sie remote-tags zu verschieben, oder warum Sie nicht verwenden können git-tag für die Atomare test-and-set

Ich habe ein problem, wo zwei ähnliche Prozesse laufen parallel in separaten Klone des gleichen repository (in der Regel auf verschiedenen Computern). Jedes mal, wenn ein Prozess ausgeführt wird, ruft es die neuesten tags aus der Fernbedienung und dann leitet eine eindeutige Nummer, die auf der Grundlage der tags, die er sieht.

E. g. wenn diese tags vorhanden auf der Fernbedienung: 1.0 1.1 1.2 1.3
dann wird ein Prozess wählen, 1.4 in der nächsten Nummer.

Bevor der Prozess gestartet wird, erstellt er einen neuen tag und schiebt diese zurück, um die Fernbedienung:

$ git tag 1.4 HEAD
$ git push origin tag 1.4

Den Idee war, dass dies ein Weg, um atomar wählen Sie zahlen. Der andere Prozess, wenn er auf der Suche zur gleichen Zeit, kann auch entscheiden, zu verwenden, 1.4, aber wenn es darum geht zu schieben, es ist tag, es sollten entdecken, dass 1,4 schon vorhanden ist, und wählen Sie 1,5 statt (und versuchen wieder).

Meine Hoffnung war, dass ich es behandeln konnte, git tag schiebt als atomic.

Leider für einige seltsame Grund, git ermöglicht remote-tags zu verschieben, die in bestimmten Situationen!

Zum Beispiel, sagen wir, Umbau 1.4 auf origin/master und geschoben. Der andere Prozess setzen will-tag 1.4, sagen, Ursprungs - /master -^, was würde das verschieben der tag nach hinten. Git dies ablehnen mit einem "non-fast-forward" Fehler:

Prozess Ein:

$ git tag 1.4 origin/master
$ git push origin tag 1.4
Total 0 (delta 0), reused 0 (delta 0)
To /repo1
 * [new tag]         1.4 -> 1.4

Prozess B:

$ git tag 1.4 origin/master^
$ git push origin tag 1.4
To /repo1
 ! [rejected]        1.4 -> 1.4 (non-fast forward)
error: failed to push some refs to '/repo1'

Ok, das ist in Ordnung, Prozess B kann versuchen 1,5 statt.

Aber betrachten Sie diese situation:

Prozess Ein:

$ git tag 1.4 origin/master
$ git push origin tag 1.4
Total 0 (delta 0), reused 0 (delta 0)
To /repo1
 * [new tag]         1.4 -> 1.4

Prozess B:

$ git tag 1.4 origin/master
$ git push origin tag 1.4
Everything up-to-date

Oh. Das ist eine Schande - git ließ nicht darauf schließen, dass dieser tag existiert bereits auf der Fernbedienung. Tatsächlich, das tut er, mit -v:

$ git push origin tag 1.4 -v
Pushing to /repo1
To /repo1
 = [up to date]      1.4 -> 1.4
Everything up-to-date

Ok, also kann ich tun, irgendeine Art von stderr umleiten, Suche nach " = ", und die es erlauben, Verfahren B, um zu bestimmen, die 1.4 ist bereits im Einsatz.

Aber das ist ein bisschen albern. Und es kommt noch schlimmer:

Prozess Ein:

$ git push origin tag 1.4
Total 0 (delta 0), reused 0 (delta 0)
To /repo1
 * [new tag]         1.4 -> 1.4

Prozess B:

$ git push origin tag 1.4
Total 0 (delta 0), reused 0 (delta 0)
To /repo1
   fd0e09e..c6cdac9  1.4 -> 1.4

Argg! Was? Git hat nur bewegt die remote-tag-ohne Vorwarnung!

Scheint es mir So, dass remote-tags in git sind grundsätzlich gebrochen - Sie sollten nur nicht "bewegen", ohne eine explizite Anforderung. Mehr zu dem Punkt, sollten Sie sich weigern, sich zu bewegen standardmäßig.

Auch die git-tag-Befehl sollte bieten eine Möglichkeit, atomar-test-und-ein-tag.

Aber eindeutig ist es nicht. Läuft git fetch first ist nicht zu helfen, denn es gibt immer noch ein Fenster von Konflikt und selbst wenn es einen Konflikt gibt, in einem der drei Szenarien der tag bewegt sich einfach!

Was ist hier Los?

Gibt es einen anderen Weg, um test-und-set-ein tag?

Wenn nicht, wie machen die Leute zuordnen und behalten build-Nummern im automatisierten build-Umgebung? Wie Sie erkennen zuverlässig, wenn zwei Prozesse haben versehentlich hob die gleiche build-Nummer?

Git 1.6.1.2.

InformationsquelleAutor davidA | 2009-07-23
Schreibe einen Kommentar