On Fri, Aug 17, 2018 at 09:28:59AM -0700, Junio C Hamano wrote:

> Jeff King <p...@peff.net> writes:
> 
> > So all of this really implies to me that you want to be able to say
> > "take this symref on the other side and update this one on the local
> > side". I.e., some way to tell a refspec "don't update the value, update
> > the symref destination". ...
> > ...
> >   git fetch origin ~HEAD:refs/remotes/origin/HEAD
> 
> We need to be a bit careful here.
> 
> You can define the meaning of the above sanely if you know that
> refmap refs/heads/*:refs/remotes/origin/* is in effect for the
> remote to read "My HEAD points at refs/heads/frotz" and interpret it
> as "In order to match, I need to make my refs/remotes/origin/HEAD to
> point at refs/remotes/origin/frotz".

Good point. I was thinking too much about the symlink itself and not its
destination. You need some way of mapping that destination, as well.

For Christian's case, it is really the "refs/*:refs/*" mapping that he
would want to emulate (because he'd be doing ~HEAD:HEAD). In some cases,
like that one, you could infer the mapping from the HEAD:HEAD itself (X
on the remote becomes X locally). But that does not work for the
refs/remotes case. You might infer from "~HEAD:refs/remotes/origin/HEAD"
that "X becomes refs/remotes/origin/X", but it is actually "refs/heads/X
becomes ...".

So yeah, this really does need pairing with the overall ref mapping.

I think that's doable even for the example I gave above, because we
could find those refspecs in the config. But:

  git fetch git://... ~HEAD:HEAD

does not have that information. We may or may not have fetched the
pointed-to ref previously.

What if this _required_ that the symref destination from the other side
also be something that we are fetching, and was otherwise an error? That
would avoid any config trickery. It does mean that "git fetch origin
~HEAD:HEAD" does not work.  But I think you'd generally want to pair it
with a fetch anyway. I.e., Either two configured refspecs, or if a
one-off fetch from a URL, fetching the branches and the symref at the
same time.

I suppose the one case it would not support is "I want to fetch HEAD as
a symref and whatever branch it points to, but I do not yet know what
that branch is". Or, I suppose, "I do not want to update any branches,
but just update my notion of HEAD" (i.e., what "remote set-head -a"
currently does).

> Also, what should the above form of "git fetch" write in FETCH_HEAD?
> Should "git pull origin ~HEAD:refs/remotes/origin/HEAD" run the fetch
> and then merge it (which may have value of refs/remotes/origin/frotz)
> to the current branch?  Should the underlying fetch be also fetching
> the frotz branch from them at the same time, or do we attempt to merge
> a possibly stale 'frotz' (which might not even have been there, the
> last time we fetched from them)?

I'd be tempted to say that a symref fetch writes nothing into FETCH_HEAD
at all. Which would make a bare "git pull origin ~HEAD" an error. I'm
sure there are cases it _could_ do something useful, but there are so
many where it doesn't make sense.

-Peff

Reply via email to