次の手順を実行すると、次のエラーが表示されます。
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.
dev
:git tag dev
git Push --tags
タグdev
を削除し、再度作成してタグをプッシュしました。
git tag -d dev
git tag dev
git Push --tags
なんでこんなことが起こっているの?
私はMacにいます。 Linux(Ubuntu)を使用している私の友人には、この問題はありません。 git Push --tags -f
を使用してタグの更新を強制できることは知っていますが、これは危険です(たとえば、ブランチではなくタグのみで誤ってコミットを書き換えるなど)。
編集、2016年11月24日:この回答は明らかに人気があるため、ここにメモを追加します。中央サーバー上のタグをreplaceした場合、oldタグ—既にタグを持っている中央サーバーリポジトリのクローンは、古いタグを保持することができます。そのため、これで方法がわかりますが、本当にwantしてください。すでに「間違った」タグを持っている全員を削除してtheir「間違ったタグ」を取得し、新しい「正しいタグ」に置き換える必要があります。 。
Git 2.10/2.11のテストでは、古いタグを保持することがgit fetch
を実行するクライアントのデフォルトの動作であり、更新がgit fetch --tags
を実行するクライアントのデフォルトの動作であることが示されています。
(元の答えは次のとおりです。)
タグをプッシュするように要求すると、git Push --tags
は(プッシュ設定からのコミットやその他のオブジェクト、およびその他のref更新とともに)new-sha1 refs/tags/name
の形式の更新要求をリモートに送信します。 (まあ、それは多くを送信します:各タグのためのそれらの1つ。)
更新要求は、リモートによってold-sha1
(または、タグごとに1つ)を追加するように変更され、その後、pre-receiveおよび/または更新フック(リモートに存在するフック)。これらのフックは、タグの作成/削除/更新を許可するか拒否するかを決定できます。
old-sha1
値は、タグが作成されている場合、すべてゼロの「null」SHA-1です。タグが削除されている場合、new-sha1
はnull SHA-1です。それ以外の場合、両方のSHA-1値は実際の有効な値です。
フックがなくても、実行される一種の「ビルトインフック」があります。「force」フラグを使用しない限り、リモートはタグの移動を拒否します(ただし、「ビルトインフック」は両方ともOKです) 「追加」および「削除」)。表示される拒否メッセージは、この組み込みフックから来ています。 (ちなみに、この同じ組み込みフックは、早送りではないブランチの更新も拒否します。)1
しかし、これが何が起こっているのかを理解するための鍵の1つです。git Push
ステップは、リモートがそのタグを現在持っているかどうか、もしそうなら、SHA-1の値を知りません。 「ここにタグの完全なリストとそのSHA-1値があります」としか書かれていません。リモートは値を比較し、追加や変更がある場合、それらに対してフックを実行します。 (同じタグについては、何もしません。あなたが持っていないタグについては、何もしません!)
タグをローカルで削除してからPush
を削除すると、Pushはタグを転送しません。リモートは、変更を加える必要がないと想定しています。
タグをローカルで削除してから、新しい場所を指すタグを作成し、Push
を押すと、Pushはタグを転送し、リモートはこれをタグ変更と見なし、強制プッシュでない限り変更を拒否します。
したがって、2つのオプションがあります。
後者はgit Push
を介して可能です2 タグをローカルで削除してもPush
ingは効果がありません。リモートの名前がOrigin
であり、削除するタグがdev
であると仮定します。
git Push Origin :refs/tags/dev
これは、タグを削除するようにリモートに要求します。ローカルリポジトリ内のタグdev
の有無は無関係です。 :remoteref
をrefspecとして使用するこの種のPush
は、純粋な削除プッシュです。
リモートは、タグの削除を許可する場合と許可しない場合があります(追加された追加フックに応じて)。削除が許可されている場合、タグはなくなり、2番目のgit Push --tags
が、コミットまたは注釈付きのタグリポジトリオブジェクトを指すローカルdev
タグを持っている場合、新しいdev
タグを送信します。リモートでは、dev
が新しく作成されたタグになるため、リモートはおそらくプッシュを許可します(これも追加のフックに依存します)。
フォースプッシュは簡単です。タグ以外の何かotherを更新しないようにする場合は、git Push
にその1つのrefspecのみをプッシュするように指示します。
git Push --force Origin refs/tags/dev:refs/tags/dev
(注:ref-specのタグを1つだけ明示的にプッシュする場合は、--tags
は不要です)。
1もちろん、このビルトインフックのreasonは、同じリモートリポジトリの他のユーザーが期待する動作を強制するのに役立ちます:ブランチはそうではありません巻き戻され、タグは移動しません。強制的にプッシュする場合は、他のユーザーにこれを実行していることを知らせて、修正できるようにする必要があります。 「タグがまったく動かない」は、Git 1.8.2によって新たに実施されることに注意してください。以前のバージョンでは、ブランチ名のように、タグがコミットグラフ内で「前に進む」ことができました。 git 1.8.2リリースノート を参照してください。
2リモートにログインできれば簡単です。そこのGitリポジトリに移動して、git tag -d dev
を実行するだけです。いずれかの方法(リモートでタグを削除するか、git Push
を使用して削除する)では、リモートにアクセスするユーザーがdev
タグが欠落していることに気付く期間があることに注意してください。 (彼らは既に自分の古いタグを持ち続けており、すでに持っていれば、プッシュ新しいタグをプッシュする前に古いタグをバックアップします。)
UPDATEタグにしたい場合、それを1.0.0
としましょう
git checkout 1.0.0
git ci -am 'modify some content'
git tag -f 1.0.0
git Push Origin --delete 1.0.0
git Push Origin 1.0.0
完了
私はこの問題に遅れているか、すでに回答されているようですが、できることは次のとおりです:(私の場合、ローカルにタグが1つしかありませんでした..古いタグを削除し、 :
git tag -d v1.0
git tag -a v1.0 -m "My commit message"
次に:
git Push --tags -f
これにより、リモートでallタグが更新されます。
危険になる可能性があります!ご自身の責任で使用してください。
拒否を取得する理由は、タグがリモートバージョンとの同期を失ったためです。これは、ブランチの場合と同じ動作です。
git pull --rebase <repo_url> +refs/tags/<TAG>
を介してリモートからタグと同期し、同期後、競合の管理が必要です。 diftoolがインストールされている場合(例:meld)git mergetool meld
を使用してリモートを同期し、変更を保持します。
-rebaseフラグを使用してプルしているのは、他の競合を避けるために、リモートの作業の上に作業を配置するためです。
また、私が理解していないのは、なぜdev
タグを削除して再作成するのですか?タグは、ソフトウェアバージョンまたはマイルストーンを指定するために使用されます。 gitタグの例v0.1dev
、v0.0.1alpha
、v2.3-cr
(cr-候補リリース)など。
これを解決する別の方法は、git reflog
を発行し、リモートでdev
タグをプッシュした瞬間に移動することです。 commit idとgit reset --mixed <commmit_id_from_reflog>
をコピーして、プッシュした時点でタグがリモートと同期しており、競合が発生しないことを確認します。