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

Re: Pushing symbolic references to remote repositories?

From
Junio C Hamano <gitster@pobox.com>
Date
Dec 21, 2012, 23:11 UTC
Message-ID
<7vip7vrof6.fsf@alter.siamese.dyndns.org>
In-Reply-To
<CAJo=hJvqptfKqM+6J8Ddfb5qcqjAU8bB_JO9VB-XVsCCf64NUQ@mail.gmail.com>
Shawn Pearce <spearce@spearce.org> writes:
Show 7 quoted lines
> On Fri, Dec 21, 2012 at 11:53 AM, Dun Peal <dunpealer@gmail.com> wrote:
>>
>> Is there a clean and reliable way to do that, or are symbolic
>> references just not meant to be shared?
>
> There is no support for symbolic references in the network protocol,
> so they cannot currently be shared by git push or git fetch.

What Shawn said is technically correct, but do not read it as "we know what protocol update we want at the network level, but we haven't got around implementing it".

It is unclear what it means to send symrefs across repositories (rather, what we want it to mean). In that sense, the reality is closer to the latter of your choices.

There are three primary kinds of symrefs to consider:
 * worktree/.git/HEAD is meant to point at the branch that is
   currently checked out.  This is designed to be under sole control
   of the person who is working in such a repository and the outside
   people have no business knowing which branch he happens to be
   working on at this very moment (it can change the next minute).
 * worktree/.git/refs/remotes/$name/HEAD is meant to point at the
   remote-tracking branch of the named remote (e.g. 'origin') the
   local user is interested in, to let "git checkout -b topic
   origin" work, instead of a longer "git checkout -b topic
   origin/master".
 * bare.git/HEAD is meant to point at the "primary" branch at a
   bare, distribution repository nobody works in directly.  The
   branch pointed at by the symref rarely, if ever, changes.

Nobody will imagine flipping worktree/.git/HEAD from outside by pushing into it (unless you are trying to pull a prank on the user who is working in that repository). Also, nobody would want to update this symref by fetching from outside. So we won't have to consider updating the first kind in the following discussion.

It is unlikely that anybody sane wants to update the remote-tracking worktree/.git/refs/remotes/origin/HEAD from outside by pushing.

It *may* make sense to update it upon fetching, though, in some cases. You first clone from bare.git/HEAD and learn [*1*] that the primary branch at the time of cloning was 'master', and remote/origin/HEAD in your repository is set to point at origin/master. Now the upstream designates a different branch as the primary (perhaps 'trunk'), and you may want your next "git fetch" to repoint your remote/origin/HEAD to point at 'remote/origin/trunk'.

However, even this one is not unconditionally a good idea. The branch you are interested in might be different from what your remote designates as its primary branch in the first place. You may for example want to follow along 'next' after cloning from me. E.g.

    $ git clone     git://git.kernel.org/pub/scm/git/git.git git
    $ cd git
    $ git symbolic-ref refs/remotes/origin/HEAD
    refs/remotes/origin/next

It is not clear if it is a good idea to allow "git fetch" to repoint your remotes/origin/HEAD to whatever I chose to point my HEAD at.

So for the second kind, pushing is irrelevant, and fetching is "perhaps sometimes it may make sense".

I think that the only one and a half sensible use cases that unconditionally make sense to update symrefs across repositories are to update bare.git/HEAD symref:

 - update bare.git/HEAD of a repository that is a local mirror of a
   more authoritative repository with "git fetch --mirror", in which
   case you do want to follow what branch is designated as the
   primary by the project you are mirroring from;
 - update bare.git/HEAD from outside by some means to change which
   branch is the primary one for the project. Only because your
   hosting site does not give you an easy way to do so, pushing from
   another repository that happens to point its HEAD at a different
   branch seems to be one plausible way to do so, but that does not
   have to be the only way.
[Footnote]

*1* We would need to update the network protocol for this purpose, as most transports do not carry this information and clone has to guess which branch bare.git/HEAD points at.

The purpose of this message, though, is to illustrate that the protocol update to carry the information is not the end of the story, but merely is an enabling beginning. We need to know what semantics we would want to implement on top of that transfer.

Previous: Shawn PearceNext: Andreas Schwab
Message 3 of 6 in “Pushing symbolic references to remote repositories?”
  1. Dun PealDec 21, 2012
  2. Shawn PearceDec 21, 2012
  3. Junio C HamanoDec 21, 2012
  4. Andreas SchwabDec 22, 2012
  5. Junio C HamanoDec 22, 2012
  6. Sitaram ChamartyDec 23, 2012

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.