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

Re: [PATCH] Make git-clone --use-separate-remote the default

From
Junio C Hamano <junkio@cox.net>
Date
Nov 24, 2006, 11:24 UTC
Message-ID
<7vslg9axzv.fsf@assigned-by-dhcp.cox.net>
In-Reply-To
<ek6glc$pn$1@sea.gmane.org>
Salikh Zakirov <Salikh.Zakirov@Intel.com> writes:
Show 13 quoted lines
> git-push.1 has following description:
>
>     Some short-cut notations are also supported.
>
>               o   tag <tag> means the same as refs/tags/<tag>:refs/tags/<tag>.
>
>               o  A parameter <ref> without a colon is equivalent to
>                  <ref>:<ref>, hence updates <ref>  in
>                  the destination from <ref> in the source.
>
> Maybe this is only my reading of manual page, but I understood
> it like it does not leave the room for ambiguity, because it is using
> _the same_ refspec as the local one.
If you write
	git push $remote tag $string
it is handled exactly as if you wrote:
	git push $remote refs/tags/${string}:refs/tags/${string}
and if you write
	git push $remote master
it is handled exactly as if you wrote:
	git push $remote master:master

The manual correctly describes the above, but the issue the fix addresses is about what happens to that 'master' string that follows the colon, and the 'master' string becomes ambiguous if the remote end uses separate-remote layout.

The way this command:
	git push $remote $src:$dst
is handled is:
 (0) send-pack gets ls-remote equivalent from the remote.  This
     tells us the set of refs the remote has and the value of
     each of them.
 (1) $src can be a ref that is resolved locally the usual way.
     You could have any valid SHA-1 expression (e.g. HEAD~6).
 (2) $dst is compared with the list of refs that the remote
     has, and unique match is found.  So if the set of refs the
     remote side has:
	refs/heads/origin
        refs/heads/master
        refs/tags/v1.0.0
     and if $dst is 'master', refs/heads/master is what will be
     updated.
 (3) Then send-pack generates and sends the necessary pack to
     update the remote side with objects needed for $src, using
     the knowledge of what the remote has.  Also, send-pack
     instructs the remote to update which ref with what value.
     Continuing with the example, it tells the remote to update
     its refs/heads/master with the value of our 'master'.
That *matching* in step (2) is what the fix is about.

The matching code of send-pack from the beginning has been the unique tail-match. When the other end had a branch 'bugfix' and a tag 'bugfix', then both of them would match because both refs/heads/bugfix and refs/tags/bugfix ends with 'bugfix' ('gfix' does not match 'refs/heads/bugfix' -- we are not that stupid ;-).

So you had to disambiguate this case by saying heads/bugfix if you want to push the branch. That was fine between branches and tags, since having a branch and a tag with the same name is usually not done in order to keep user's sanity.

However, separate-remote layout poses a more serious problem, because most of the time you would expect to see similar names under refs/heads/ and refs/remotes/origin/ directories. If we kept the original ref matching code, a cloned remote would have both refs/heads/master and refs/remotes/origin/master almost always, so somebody who is pushing 'master' to such a remote would have had to disambiguate it by saying:

	git push heads/master

which is (as described in the part of the manual you quoted) a shorthand for

	git push heads/master:heads/master

'heads/master' before the colon is used to find out which commit in your local repository we are pushing, and 'heads/master' after the colon is used to match against the list of refs from the remote (which contains both 'refs/heads/master' and 'refs/remotes/origin/master'), and only because the user said 'heads/master' (not just 'master') this avoids ambiguity.

Even under separate-remote layout, we would want to be able to say:

	git push master

to mean we want to push to remote's heads/master when the remote has remotes/{origin,blech}/master.

And that is what the fix is about.
Previous: Salikh ZakirovNext: Salikh Zakirov
Message 10 of 17 in “Make git-clone --use-separate-remote the default”
  1. Make git-clone --use-separate-remote the defaultPetr Baudis, Nov 23, 2006
  2. Junio C HamanoNov 23, 2006
  3. Andy WhitcroftNov 23, 2006
  4. Petr BaudisNov 23, 2006
  5. J. Bruce FieldsNov 23, 2006
  6. Junio C HamanoNov 24, 2006
  7. Junio C HamanoNov 24, 2006
  8. Junio C HamanoNov 24, 2006
  9. Salikh ZakirovNov 24, 2006
  10. Junio C HamanoNov 24, 2006
  11. Salikh ZakirovNov 24, 2006
  12. Salikh ZakirovNov 24, 2006
  13. Junio C HamanoNov 25, 2006
  14. Sergey VlasovNov 24, 2006
  15. Junio C HamanoNov 24, 2006
  16. Jakub NarebskiNov 24, 2006
  17. Salikh ZakirovNov 24, 2006

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.