Search code examples
gitaliasgit-push

Why does "git push origin @" not work?


We can push the head of a branch like below

$ git push origin HEAD

And, we can use @ for alias of HEAD.

$ git show @

Then why does the below command gives me an error?

$ git push origin @
fatal: remote part of refspec is not a valid name in @

Solution

  • Although @ can be used to specify HEAD, you first need @ to be parsed as a ref. The syntax for git push takes a refspec, and in that context, @ is given two different meanings, only one of which is a ref.

    The syntax for a refspec in git push is [+]<src>[:<dst>]. + is optional. :<dst> is optional if it can be resolved from <src>.

    git push origin HEAD works, because HEAD is treated as a very special case: HEAD is normally a symbolic ref to a specific branch, and git push resolves symbolic refs and selects <dst> based on the pointed-to branch name.

    You can also have, for example, git symbolic-ref MYMASTER refs/heads/master, followed by git push origin MYMASTER.

    git push origin HEAD~0 fails, because it translates to git push origin HEAD~0:HEAD~0, and a remote refname HEAD~0 is not valid, even though HEAD~0 will necessarily always specify the exact same commit as HEAD.

    git push origin @ fails, because it translates to git push origin @:@, and a remote refname @ is not valid, even though @ will necessarily always specify the exact same commit as HEAD.

    git push origin @:HEAD would almost work, if you have a remote branch named HEAD. This is not the special case where the refspec is simply HEAD, so this does not resolve HEAD based on any symbolic ref.

    git push origin @:master does work.