gitの「src refspec refs/heads/master matches more than one」ってエラーの直し方

GitHub Actionsでタグを打ったら自動でコンパイルしてリリースしてくれるというのをやりたかったのですが、その過程で以下のようなエラーが出るようになってしまいました。

$ git push
error: src refspec refs/heads/master matches more than one
error: failed to push some refs to 'origin:refs/tags/master'

pushしてもpullしても同じエラー。なんだかよく分からない。

TL;DR: 直し方

以下のコマンドで直りました。

$ git tag -d refs/heads/master
$ git push origin :refs/tags/refs/heads/master
To github.com:macrat/some-repository.git
 - [deleted]         refs/heads/master

試行錯誤と原因究明

最初に試したこと

エラーメッセージで調べてみたところ、以下のブログ記事を見つけました。

ブランチ名とタグ名を同じにしたら怒られた件 - helen's blog

これによると、ブランチ名と同じタグが出来てしまっているのが原因らしい。

というわけで、リモートのmasterタグを消そうとしてみる。

$ git push origin :refs/tags/master
remote: warning: Deleting a non-existent ref.
To github.com:macrat/some-repository.git
 - [deleted]         master

non-existentらしい。消えなかった。 そして当然直らなかった。

ちゃんと状況を調べた

あらためてGitHubを見てみると、こんなことになっていました。

refs/tags/の部分はgitの内部的なナニカかと思っていたけれど、まさかのタグ名の一部だった…。

コマンドラインでもちゃんとそれが見れてました。

$ git tag
refs/tags/master
v1.0.0
v1.0.1
v1.0.2
v1.0.3
v1.0.4
v1.0.5
v1.0.6
v1.1.0

判明した原因

GitHub Actionsでやりたかったのは「タグを打ったらそのタグ名でリリースを作る」だったのですが、 デバッグの過程で「masterにプッシュしたら」という条件にしていたのでした。

「そのタグ名」を取得するためにgithub.refというコンテキストを使用していました。 このgithub.refというやつ、masterにpushされて動くときはrefs/heads/masterという名前になっているようで…

結果として、refs/heads/masterという名前のリリース(とタグ)が作られてしまったのでした。

改めて、直し方

というわけで、「リモート(refs/tags/)にあるrefs/heads/masterという名前のタグを消去せよ」というコマンドを打つ必要があります。 それが冒頭に書いた以下のコマンド。

$ git push origin :refs/tags/refs/heads/master
To github.com:macrat/some-repository.git
 - [deleted]         refs/heads/master

ややこしく見えますが、意味が分かればそこまででも無いはず?

もう一つ実行している以下のコマンドは、念の為ローカルにあるrefs/heads/masterを削除するためのコマンドです。

$ git tag -d refs/heads/master

分かればなんてことないですが、スラッシュだらけで見た目がヤバそうなエラーでした…。