同じリポジトリの別々のクローン (通常は別々のコンピュータ) 内で 2 つの同様のプロセスが並行して実行されているという問題があります。プロセスが実行されるたびに、リモートから最新のタグを取得し、検出したタグに基づいて一意の番号を推測します。
たとえば、これらのタグがリモートに存在する場合: 1.0 1.1 1.2 1.3 プロセスは次の番号として 1.4 を選択します。
プロセスが開始する前に、新しいタグを作成し、これをリモートにプッシュします。
$ git tag 1.4 HEAD
$ git push origin tag 1.4
アイデアは、これがアトミックに数値を選択する方法であるというものでした。他のプロセスは、同時に見ている場合、1.4 を使用することを決定する可能性がありますが、そのタグをプッシュすると、1.4 が既に存在することを発見し、代わりに 1.5 を選択する必要があります (そして再試行します)。
私の希望は、git タグのプッシュをアトミックとして扱えることでした。
残念ながら、奇妙な理由により、git は特定の状況でリモートタグを移動することを許可しています!
たとえば、タグ 1.4 が origin/master に配置され、プッシュされたとします。もう 1 つのプロセスは、たとえば origin/master^ にタグ 1.4 を配置しようとしていますが、これにはタグを後方に移動する必要があります。Git はこれを「非早送り」エラーで拒否します。
プロセスA:
$ 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
プロセス 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'
プロセス B はこれを使用して、代わりに 1.5 を試すことができます。
しかし、次の状況を考慮してください。
プロセスA:
$ 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
プロセス B:
$ git tag 1.4 origin/master
$ git push origin tag 1.4
Everything up-to-date
おー。それは残念です-gitは、このタグがリモートに既に存在することを示していませんでした。実際、-v を使用すると、次のようになります。
$ git push origin tag 1.4 -v
Pushing to /repo1
To /repo1
= [up to date] 1.4 -> 1.4
Everything up-to-date
わかりましたので、ある種の stderr リダイレクトを実行し、「 = 」を検索すると、プロセス B は 1.4 が既に使用されていると判断できます。
しかし、それは少しばかげています。さらに悪化します:
プロセスA:
$ git push origin tag 1.4
Total 0 (delta 0), reused 0 (delta 0)
To /repo1
* [new tag] 1.4 -> 1.4
プロセス B:
$ git push origin tag 1.4
Total 0 (delta 0), reused 0 (delta 0)
To /repo1
fd0e09e..c6cdac9 1.4 -> 1.4
アーグ!何?Git は警告なしにリモート タグを移動しました!
したがって、git のリモート タグは根本的に壊れているように思えます。明示的な要求なしに単に「移動」するべきではありません。さらに言えば、デフォルトで移動を拒否する必要があります。
また、git-tag コマンドは、タグをアトミックにテストおよび設定する方法を提供する必要があります。
しかし、明らかにそうではありません。最初に git fetch を実行しても、まだ競合のウィンドウが存在するため、役に立ちません。競合があったとしても、3 つのシナリオのいずれかでタグが移動するだけです。
ここで何が起こっているのですか?
タグをテストして設定する別の方法はありますか?
そうでない場合、自動化されたビルド環境でビルド番号をどのように割り当てて予約しますか? 2 つのプロセスが誤って同じビルド番号を取得したことを確実に検出するにはどうすればよいでしょうか?
git 1.6.1.2 を使用。