158

以下の手順を実行すると、次のエラーが表示されます。

To git@provider.com:username/repo-name.git
 ! [rejected]        dev -> dev (already exists)
error: failed to push some refs to 'git@provider.com:username/repo-name.git'
hint: Updates were rejected because the tag already exists in the remote.
  1. リポジトリを作成しました
  2. ローカル マシンでレポを複製しました。
  3. README ファイルを変更し、変更をコミットしてコミットをプッシュしました。
  4. タグを作成しましたdev:git tag dev
  5. プッシュされたタグ:git push --tags
  6. README ファイルを変更し、変更をコミットしてコミットをプッシュしました。
  7. tag を削除devし、再度作成してタグをプッシュしました:

    git tag -d dev
    git tag dev
    git push --tags
    

なぜこうなった?

私はマックにいます。Linux (Ubuntu) を使用している私の友人には、この問題はありません。git push --tags -fタグの更新を強制するために使用できることはわかっていますが、これは危険です (たとえば、ブランチではなくタグでのみ行われたコミットを誤って書き換えるなど)。

4

8 に答える 8

185

編集、2016 年 11 月 24 日: この回答は明らかに人気があるため、ここにメモを追加します。中央サーバーのタグを置き換えると、古いタグを持つ人 (タグを既に持っている中央サーバー リポジトリのクローン) は、古いタグを保持できます。したがって、これはその方法を示していますが、本当にやりたいことを確認してください。すでに「間違った」タグを持っているすべての人に、「間違ったタグ」を削除て、新しい「正しいタグ」に置き換える必要があります。

Git 2.10/2.11 でのテストでは、古いタグの保持が を実行しているクライアントgit fetchのデフォルトの動作であり、更新が を実行しているクライアントのデフォルトの動作であることが示されていますgit fetch --tags

(元の回答は次のとおりです。)


タグのプッシュを要求すると、git push --tags(必要なコミットやその他のオブジェクト、およびプッシュ設定からのその他の ref 更新とともに) フォームの更新要求がリモートに送信されます。(まあ、それはいくらでも送信します: 各タグのそれらの 1 つ。)new-sha1 refs/tags/name

更新要求はリモートによって変更されてold-sha1(またはタグごとに 1 つ) 追加され、pre-receive および/または update フック (リモートに存在するフック) に配信されます。これらのフックは、タグの作成/削除/更新を許可するか拒否するかを決定できます。

old-sha1タグが作成されている場合、値はすべてゼロの「null」SHA-1 です。new-sha1タグが削除されている場合、これは null SHA-1 です。それ以外の場合、両方の SHA-1 値は実際の有効な値です。

フックがなくても、実行される一種の「組み込みフック」があります。「強制」フラグを使用しない限り、リモートはタグの移動を拒否します (ただし、「組み込みフック」は両方で常に問題ありません)。 「追加」と「削除」)。表示されている拒否メッセージは、この組み込みフックからのものです。(ちなみに、この同じ組み込みフックは、早送りではないブランチの更新も拒否します。) 1

しかし、これが何が起こっているのかを理解するための鍵の 1 つです。このgit pushステップでは、リモコンが現在そのタグを持っているかどうか、もしそうなら、どのような SHA-1 値を持っているかを知りません。「これがタグの完全なリストとそのSHA-1値です」とだけ書かれています。リモートは値を比較し、追加や変更がある場合は、それらに対してフックを実行します。(同じタグの場合は何もしません。持っていないタグの場合も何もしません!)

タグをローカルで削除するとpush、プッシュは単にタグを転送しません。リモートは、変更を行うべきではないと想定しています。

タグをローカルで削除し、新しい場所を指すタグを作成するとpush、プッシュによってタグが転送され、リモートはこれをタグの変更と見なし、強制プッシュでない限り変更を拒否します。

したがって、次の 2 つのオプションがあります。

  • 強制プッシュを行う、または
  • リモコンのタグを削除します。

後者、ローカルでタグを削除してing しても効果がない場合でも、 git push2を介して可能です。リモートの名前が で、削除するタグpushが であると仮定します。origindev

git push origin :refs/tags/dev

これにより、リモートにタグを削除するように求められます。devローカル リポジトリにタグが存在するかどうかは関係ありません。refspec としてのこの種のはpush、 pure-delete プッシュです。:remoteref

リモートは、タグの削除を許可する場合と許可しない場合があります (追加された追加のフックによって異なります)。削除が許可されている場合、タグはなくなり、2 つ目は、コミットまたは注釈付きのタグ リポジトリ オブジェクトを指すgit push --tagsローカル タグがある場合に、新しいタグを送信します。リモートでは が新しく作成されたタグになるため、リモートはおそらくプッシュを許可します (これも、追加された追加のフックに依存します)。devdevdev

強制プッシュはより簡単です。タグ以外更新しないようにしたい場合は、git pushその 1 つの refspec のみをプッシュするように指示してください。

git push --force origin refs/tags/dev:refs/tags/dev

--tags(注:タグ ref-spec を 1 つだけ明示的にプッシュする場合は必要ありません)。


1もちろん、この組み込みフックの理由は、同じリモート リポジトリの他のユーザーが期待する動作 (ブランチが巻き戻されず、タグが移動しない) を強制するのに役立つことです。強制的にプッシュする場合は、他のユーザーにこれを行っていることを知らせて、修正できるようにする必要があります。Git 1.8.2 では、「タグはまったく移動しない」が新たに適用されることに注意してください。以前のバージョンでは、ブランチ名と同じように、コミット グラフ内でタグを「前方に移動」できました。git 1.8.2 リリース ノートを参照してください。

2リモートでログインできれば簡単です。そこの Git リポジトリに移動して、 を実行するだけgit tag -d devです。リモコンでタグを削除するか、または を使用してタグを削除するかに関係なく、リモコンにアクセスした人がタグがないgit pushことに気付く期間があることに注意してください。(彼らは独自の古いタグをdev持っている場合は、引き続き古いタグを持ち、新しいタグをプッシュする前に古いタグをプッシュすることさえあります。)

于 2013-10-10T15:30:06.713 に答える
59

Mac SourceTree でのみ、[すべてのタグをプッシュ]チェックボックスをオフにします。

ここに画像の説明を入力

于 2015-12-02T09:59:34.523 に答える
22

SourceTreeを使用している場合は非常に簡単です

ここに画像の説明を入力 基本的には、競合するタグを削除して再度追加するだけです:

  1. タブに移動しますリポジトリ->タグ->タグの削除
  2. 競合するタグ名を選択してください
  3. すべてのリモコンからタグを削除にチェックを入れる
  4. 削除を押します
  5. 適切なコミットに同じ名前の新しいタグを作成します
  6. 変更をリモートにプッシュするときにすべてのタグをプッシュするを必ずチェックしてください
于 2016-12-15T14:06:46.143 に答える
20

私はこの問題に遅れているか、すでに回答されているようですが、できることは次のとおりです:(私の場合、ローカルにタグが1つしかなかったので..古いタグを削除して、 :

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

それで:

git push --tags -f

これにより、リモートのすべてのタグが更新されます。

危ないかも!自己責任で使用してください。

于 2016-08-26T13:57:08.647 に答える
2

Windows SourceTree で、 のチェックを外しPush all tags to remotesます。

ここに画像の説明を入力

于 2016-02-22T12:35:07.683 に答える