git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: error with $ git push origin HEAD:newbranch

From
Jeff King <peff@peff.net>
Date
May 6, 2011, 17:02 UTC
Message-ID
<20110506170204.GA16576@sigill.intra.peff.net>
In-Reply-To
<loom.20110506T034552-210@post.gmane.org>
On Fri, May 06, 2011 at 02:16:03AM +0000, chris wrote:
Show 21 quoted lines
> Jeff King <peff <at> peff.net> writes:
> > 
> > On Thu, May 05, 2011 at 10:06:21AM +0000, chris wrote:
> > 
> > > It is slightly surprising that git-push doesn't default to assuming 
> > > one means refs/heads/newbranch in this case.  I don't see a reason 
> > > not to?
> > 
> > Consider something like:
> > 
> >   $ git checkout v1.5
> >   $ git push origin HEAD:foo
> > 
> > Would you want "foo" to be a branch or a tag? I can see arguments for
> > either.
> 
> If the above command wanted to produce a tag, just provide 'v1.5' as the source 
> ref.  It seems to me that first checking out the tag then pushing from HEAD is 
> extra steps in order to push a branch ref without having to be explicit about 
> it.  $ git push origin v1.5:foo would have been simpler if intending to push a 
> tag ref.

Sure, but that was just a small example. It could just as easily have been:

  $ git checkout v1.5
  ... look look look ...
  ... hmm, this one doesn't have the bug or feature I'm looking for ...
  $ git checkout v1.5.1
  ... look look look ...
  ... nor this one ...
  $ git checkout v1.5.2
  ... look look look ...
  ... oh, this one has it, let's push it upstream to communicate to
      somebody ...
  $ git push origin HEAD:foo

Sure, I _could_ say "git push origin v1.5.2:foo" in the final step. But my mental model is "I have found the thing I am looking for, now push it", which means HEAD is more natural. This is more obvious to see when you start leaving refs, like:

  $ git checkout HEAD^
  ... look look look; nope ...
  $ git checkout HEAD^
  ... look look look; nope ...
  $ git checkout HEAD^
  ... yep, found it ...
  $ git push origin HEAD:foo

So in both of those cases, what should be pushed? A tag or a branch? My argument is that git would have to guess. Rather than guess, we come back to the user and say "please be more specific".

> Given that git-push has specific syntax for pushing a tag, and git-push makes 
> other assumptions that give the perception it is generally used for branches 
> unless told otherwise also makes me expect that "foo" to be a branch.

That tag syntax is antique and predates most of the nice DWIM behavior of refspecs. Nowadays you can just say "git push <remote> v1.5" and it will do the same thing without the "tag" modifier. So I doubt anyone uses it.

I wonder if we should more clearly mark it as useless in the documentation.

Show 12 quoted lines
> The following is provided for specifically calling out a tag:
> 
>   $ git push origin tag <refspec>
> 
> However, that syntax as far as I can tell is pretty worthless anyway, as the 
> following will not work:
> 
>   $ git push origin tag HEAD:newtag
>   error: src refspec refs/tags/HEAD does not match any.
> 
>   $ git push origin tag 183c65e:newtag
>   error: src refspec refs/tags/183c65e does not match any.

Right. It's literally about expanding "tag foo" into "refs/tags/foo:refs/tags/foo". So it only works for a tag ref.

For both of those, you would need:
  git push origin HEAD:refs/tags/newtag
  git push origin 183c65e:refs/tags/newtag
Show 9 quoted lines
> But both the following are successful, which makes me ask why the 'tag' option 
> exists if the above doesn't work.
> 
>   $ git push tag existingtag:newtag1
> 
>   $ git push existingtag:newtag2
> 
> So I see little purpose in the $ git push tag <refspec> syntax, as the source 
> must already be a tag anyway.

Right. Once upon a time, that didn't Just Work. These days we see that the LHS of the refspec is a tag, and infer that the RHS should be, as well (in the absence of anything more specific).

Show 13 quoted lines
> Personally, I would prefer that git-push work on branches by default[1], 
> providing shortcuts for pushing tag[2] refs and remote branch[3] refs, while all 
> other ref types must be called out explicitly.  Creating new refs isn't 
> destructive, so it seems these could be supported without concern.
> 
> 1. $ git push origin SHA1:branch1
>   => $ git push origin SHA1:refs/heads/branch1
> 
> 2. $ git push origin tag SHA1:tagname
>   => $ git push origin SHA1:refs/tags/tagname
> 
> 3. $ git push origin SHA1:upstream/branch2
>   => $ git push origin SHA1:refs/remotes/upstream/branch2

In (3), how do you differentiate between the branch "refs/heads/upstream/branch2" and the remote tracking branch "refs/remotes/upstream/branches"?

-Peff
Previous: chrisNext: chris
Message 8 of 11 in “error with $ git push origin HEAD:newbranch”
  1. chrisMay 5, 2011
  2. Jeff KingMay 5, 2011
  3. chrisMay 5, 2011
  4. Jeff KingMay 5, 2011
  5. chrisMay 6, 2011
  6. Junio C HamanoMay 6, 2011
  7. chrisMay 6, 2011
  8. Jeff KingMay 6, 2011
  9. chrisMay 10, 2011
  10. Jeff KingMay 10, 2011
  11. chrisMay 11, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.