Mark Needham

Thoughts on Software Development

git: Having a branch/tag with the same name (error: dst refspec matches more than one.)

with 3 comments

Andres and I recently found ourselves wanting to delete a remote branch which had the same name as a tag and therefore the normal way of doing that wasn’t worked out as well as we’d hoped.

I created a dummy repository to recreate the state we’d got ourselves into:

$ echo "mark" > README
$ git commit -am "readme"
$ echo "for the branch" >> README 
$ git commit -am "for the branch"
 
$ git checkout -b same
Switched to a new branch 'same'
 
$ git push origin same
Counting objects: 5, done.
Writing objects: 100% (3/3), 263 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://git@bitbucket.org/markhneedham/branch-tag-test.git
 * [new branch]      same -> same
 
$ git checkout master
$ echo "for the tag" >> README
$ git commit -am "for the tag"
$ git tag same
$ git push origin refs/tags/same
Counting objects: 5, done.
Writing objects: 100% (3/3), 266 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://git@bitbucket.org/markhneedham/branch-tag-test.git
 * [new tag]         same -> same

We wanted to delete the remote ‘same’ branch and the following command would work if we hadn’t created a tag with the same name. Instead it throws an error:

$ git push origin :same
error: dst refspec same matches more than one.
error: failed to push some refs to 'ssh://git@bitbucket.org/markhneedham/branch-tag-test.git'

We learnt that what we needed to do was refer to the full path for the branch when trying to delete it remotely:

$ git push origin :refs/heads/same
To ssh://git@bitbucket.org/markhneedham/branch-tag-test.git
 - [deleted]         same

To delete the tag we could do the same thing:

$ git push origin :refs/tags/same
remote: warning: Deleting a non-existent ref.
To ssh://git@bitbucket.org/markhneedham/branch-tag-test.git
 - [deleted]         same

Of course the tag and branch still exist locally:

$ ls -alh .git/refs/heads/
total 16
drwxr-xr-x  4 markhneedham  wheel   136B 13 Jun 23:09 .
drwxr-xr-x  5 markhneedham  wheel   170B 13 Jun 22:39 ..
-rw-r--r--  1 markhneedham  wheel    41B 13 Jun 23:08 master
-rw-r--r--  1 markhneedham  wheel    41B 13 Jun 23:08 same
 
$ ls -alh .git/refs/tags/
total 8
drwxr-xr-x  3 markhneedham  wheel   102B 13 Jun 23:08 .
drwxr-xr-x  5 markhneedham  wheel   170B 13 Jun 22:39 ..
-rw-r--r--  1 markhneedham  wheel    41B 13 Jun 23:08 same

So we got rid of them as well:

$ git checkout master
Switched to branch 'master'
$ git branch -d same
Deleted branch same (was 08ad88c).
$ git tag -d same
Deleted tag 'same' (was 1187891)

And now they are gone:

$ ls -alh .git/refs/heads/
total 8
drwxr-xr-x  3 markhneedham  wheel   102B 13 Jun 23:16 .
drwxr-xr-x  5 markhneedham  wheel   170B 13 Jun 22:39 ..
-rw-r--r--  1 markhneedham  wheel    41B 13 Jun 23:08 master
$ ls -alh .git/refs/tags/
total 0
drwxr-xr-x  2 markhneedham  wheel    68B 13 Jun 23:16 .
drwxr-xr-x  5 markhneedham  wheel   170B 13 Jun 22:39 ..

Out of interest we’d ended up with this situation by mistake rather than by design but it was still fun to do a little bit of git digging to figure out how to solve the problem we’d created for ourselves.

Be Sociable, Share!

Written by Mark Needham

June 13th, 2013 at 10:18 pm

Posted in Version Control

Tagged with

  • bedge

    Great tip this:
    git push origin :refs/tags/same
    Or, for a slightly easier to remember variant:
    git push origin –delete refs/heads/same

  • aasha medhi

    Great post. Thanks a lot

  • funroll

    Thanks for this! Here was the only part I needed at the moment: `git push origin :refs/heads/same`