11/07/2020

Git: dst refspec matches more than one

error: dst refspec release matches more than one
error: failed to push some refs to 'git@github.com:you/project.git'

A branch and a tag share that name. git push origin release has to resolve release to exactly one thing on the remote, it finds refs/heads/release and refs/tags/release, and it refuses rather than picking one.

See which refs collided:

git show-ref release
9f2c1a4b...  refs/heads/release
3d81e07c...  refs/tags/release

Push the one you meant, without deleting anything:

git push origin refs/heads/release:refs/heads/release

Spelling the refspec out in full removes the ambiguity, and it is the answer when you legitimately want both the branch and the tag to exist.

If the tag was the mistake

Delete it locally and on the remote:

git tag -d release
git push origin :refs/tags/release

The :refs/tags/ form is a push with an empty source, which is how git spells "delete that ref". Note it is refs/tags/release and not just release — without the prefix you are back in the same ambiguity that started this.

Why git will not just pick one

Because either choice is destructive in a way it cannot undo for you. Push the branch when you meant the tag and a release marker silently moves; push the tag when you meant the branch and the branch never gets there while the command reports success. Refusing is the only answer that cannot quietly do the wrong thing.

Not colliding in the first place

This turns up most on long-lived branches that people also tag at intervals — a release branch tagged release at each cut. Give the tag something the branch cannot have:

git tag release-2026-09-03
git tag release-v4.2.0

A date or a version is enough. The rule of thumb is that a branch is a place work happens and a tag is a moment work reached, so if the two share a name, one of them is misnamed.

Questions this keeps raising

How do I find out what the name matches?

git show-ref <name> lists every ref whose path ends with that name, with its full refs/heads/ or refs/tags/ path. That tells you immediately whether you are looking at a branch and a tag, or something less obvious like a remote-tracking ref.

Can I push without deleting the tag?

Yes. git push origin refs/heads/NAME:refs/heads/NAME spells out both sides of the refspec, so nothing has to be guessed. Use that whenever you want the branch and the tag to keep existing.

Why does the same push work for my colleague?

Because the ambiguity is local to whoever has both refs. If they never fetched the tag, the name resolves to one thing for them and the push goes through. git fetch --tags will reproduce the error on their machine.

Does this happen with remote branches too?

It can. Any two refs whose paths end in the same name will do it - most often a branch and a tag, occasionally a branch and a remote-tracking ref of the same name. show-ref is the way to tell, and the fully-qualified refspec is the way through regardless.