Lets say I'm in a detached HEAD state and I run the following command:
git push origin HEAD:foo
git will output the following error:
error: The destination you provided is not a full refname (i.e.,
starting with "refs/"). We tried to guess what you meant by:
- Looking for a ref that matches 'foo' on the remote side.
- Checking if the <src> being pushed ('HEAD')
is a ref in "refs/{heads,tags}/". If so we add a corresponding
refs/{heads,tags}/ prefix on the remote side.
Neither worked, so we gave up. You must fully qualify the ref.
hint: The <src> part of the refspec is a commit object.
hint: Did you mean to create a new branch by pushing to
hint: 'HEAD:refs/heads/foo'?
error: failed to push some refs to 'https://server/DefaultCollection/Project/_git/Repo'
So my question is: What is the correct keyword to use here instead of "HEAD" to reference the current commit I'm on? I can copy paste the commit id, but that's obviously silly. I'm asking for a constant name I can type, like head, to represent the current commit I'm on.
As jthill notes, when
HEADis detached, Git doesn't know whether:is meant to create
refs/heads/foo(a branch namedfoo) onorigin, orrefs/tags/foo(a tag namedfoo) onorigin, or perhaps some other kind of ref (e.g., Gerrit's magicrefs/for/foo1).Because you are in detached-HEAD mode in your current working tree, you must assist Git here. You can:
to tell Git: Use
HEAD, in all upper case,2 to find the commit in my repository. Push that commit and any necessary parents toorigin, then askoriginto create a branch namedfoo.It's probably easier, though, to just go ahead and create a local branch named
foo:after which
git push -u origin @suffices. You might even wish to make an alias (shell alias or Git alias) or shell function out of this:where
push-new-asexpands togit switch -c $1 && git push -u origin @for instance. (Add additional protections, such as making sure there's noorigin/foofirst, if you like: that's probably actually a good idea. Have the alias-or-shell-function rungit fetch originfirst.)1Gerrit is written in JGit and doesn't implement Git quite the same as C Git. Pushing to a
refs/for/namespace name creates a Gerrit changeset, which Gerrit sneakily renames into yet another name. Your own (probably C-Git based) Git thinks Gerrit createdrefs/for/foosuccessfully, as their JGit implemention returns a success indication at this point, but it really didn't. This little lie facilitates useful work and causes no actual problems, but it's definitely rather magic.2See HEAD vs head vs detached HEAD for why the upper vs lower case distinction is important.