When I try to delete a non-existent remote Git branch by name, I expectedly get an error:
$ git push origin --delete non/existent
error: unable to delete 'non/existent': remote ref does not exist
error: failed to push some refs to '[email protected]:<_replaced_>.git'
$ echo $?
1
However, deleting the same branch by ref (e.g. taken from .git/config) is not considered an error:
$ git push origin --delete refs/heads/non/existent
remote: warning: Deleting a non-existent ref.
To github.com:<_replaced_>.git
- [deleted] non/existent
$ echo $?
0
Why so? Are these commands equivalent?
They are not equivalent.
A ref is either fully qualified, i.e., starts with
refs/, and is therefore unambiguous, or is not fully qualified, i.e., starts with something other thanrefs/.A not-fully-qualified ref must be converted to a fully-qualified ref. It is up to the target of your
git pushto do the qualifying. If it finds no fully qualified ref, it reports back to the source of thegit pushthat it was unable to qualify the ref.A fully-qualified ref is of course already fully-qualified, so the receiving Git just says "ok, that doesn't exist" and hence the Git asking for the deletion is happy to report that the ref does not exist. So the Git running
git push --deleteis happy and thinks all is well.One can argue that it would be reasonable for the Git doing the
git pushto realize that "I can't qualify that ref for you" probably means "I don't have anything that would match" which in turn means "whatever ref you meant, it doesn't exist", which could then make the Git runninggit push --deletehappy. But that's not what actually happens.Note that with an ambiguous ref, that matches two or more possibilities, I observe the following:
and: