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

Re: Q: how can i find the upstream merge point of a commit?

From
Jeff King <peff@github.com>
Date
Jun 15, 2011, 23:00 UTC
Message-ID
<20110615230033.GB19803@sigill.intra.peff.net>
In-Reply-To
<201106150145.12912.johan@herland.net>
On Wed, Jun 15, 2011 at 01:45:12AM +0200, Johan Herland wrote:
Show 56 quoted lines
> > What happens if I ask for foo/bar/baz? Should it try to resolve:
> > 
> >   1. refs/remotes/foo/heads/bar/baz
> > 
> > or
> > 
> >   2. refs/remotes/foo/bar/heads/baz
> > 
> > or both (and if both, in which order)?
> 
> I think we want to do both, following these pseudo-bash steps (or something 
> similar):
> 
>   shorthand=$1  # e.g. "foo/bar/baz"
>   for remote in $(git remote)
>   do
>       case $shorthand in
>         "$remote/"*)
>           # Found matching remote
>           trailer=${shorthand#$remote/}
>           # Assert $remote/$trailer == $shorthand
>           # DWIM $trailer into
>           # - refs/heads/$trailer
>           # - refs/tags/$trailer
>           # etc.
>           for dwimmed_ref in dwim_ref($trailer)
>           do
>               # Map $dwimmed_ref through refspec to get
>               # remote-tracking ref, e.g. mapping
>               # "refs/heads/spam" to "refs/remotes/$remote/heads/spam"
>               remote_ref=map_through_refspec($dwimmed_ref, $remote)
>               if test -n "$remote_ref"
>               then
>                   # Add $remote_ref to list of candidates
>               fi
>           done
>           ;;
>         *)
>           # Non-match, ignore
>           ;;
>       esac
>   done
> 
>   # We now have a list of (fully qualified) ref candidates
>   # for $shorthand.
> 
>   # If there are zero candidates, there is no match for $shorthand.
> 
>   # If there is only one candidate, we have found an unambiguous
>   # match for $shorthand.
> 
>   # If our current context demands a SHA1 object name, and all
>   # candidates point to the same SHA1, there is no ambiguity.
> 
>   # Otherwise, $shorthand is ambiguous.
> 

The current code doesn't care about configured remotes at all. It simply looks for $X in:

  refs/remotes/$X
and
  refs/remotes/$X/HEAD

So it is not the configured remotes which are special, but rather that is a special namespace. For remotes configured with the default refspecs, it ends up the same. But it also lets me do stuff like:

  # one-off fetch, but put it somewhere useful to us
  git fetch git://host/foo.git refs/heads/*:refs/remotes/foo/*
and then still get the shortcut of "foo/master".
I think adapting that to your scheme is pretty straighforward, though.
Given 1/2/3, you would look for tags in:
  refs/remotes/1/tags/2/3
  refs/remotes/1/2/tags/3
and then similarly heads in:
  refs/remotes/1/heads/2/3
  refs/remotes/1/2/heads/3

And then complain of ambiguity if they both match (which will almost _never_ happen, unless you have a totally insane repo setup. So this is really just about having well-defined rules just in case, and probably won't affect most people in practice. In most cases, it will just DWYM).

The "HEAD" thing remains simple. You check for:
  refs/remotes/1/2/3/HEAD
since HEAD is going to be at the top-level anyway.
Show 11 quoted lines
> Using the above (pseudo)code, and assuming remotes "foo" and "foo/bar" exist 
> (with remote branches "bar/baz" and "baz", respectively, and default new-
> style refspecs), then the "foo/bar/baz" shorthand would resolve to the 
> following two remote-tracking branches:
> 
> - refs/remotes/foo/heads/bar/baz
> - refs/remotes/foo/bar/heads/baz
> 
> This would likely result in an "ambiguous shorthand" error, unless the 
> current context wants a SHA1 object name, and the two remote-tracking refs 
> happen to point to the same SHA1 (in which case the result is unambiguous).

Yeah, I think I was just being dumb asking about the order. Of course it shouldn't matter because we should complain of ambiguity.

Show 8 quoted lines
> FWIW, if I run "git log some_topic" and "some_topic" only exists as a 
> remote-tracking ref ("refs/remotes/origin/heads/some_topic"), I do think I 
> would prefer git to DWIM it, instead of simply failing with:
> 
>   fatal: bad revision: some_topic
> 
> This would be somewhat in line with the DWIMing already performed by "git 
> checkout some_topic".

I'm not sure I agree, but then I'm not sure I really like the "git checkout" DWIM, either. :)

However, I think this is an orthogonal topic to the reorganization of the refs. So one doesn't have to come with the other.

-Peff
Previous: Johan HerlandNext: Junio C Hamano
Message 14 of 19 in “Q: how can i find the upstream merge point of a commit?”
  1. Ingo MolnarJun 8, 2011
  2. Johannes SixtJun 8, 2011
  3. Stephen RothwellJun 8, 2011
  4. Peter ZijlstraJun 8, 2011
  5. Stephen RothwellJun 8, 2011
  6. Peter ZijlstraJun 8, 2011
  7. Ingo MolnarJun 8, 2011
  8. Sverre RabbelierJun 8, 2011
  9. Ingo MolnarJun 8, 2011
  10. Nguyen Thai Ngoc DuyJun 8, 2011
  11. Johan HerlandJun 14, 2011
  12. Jeff KingJun 14, 2011
  13. Johan HerlandJun 14, 2011
  14. Jeff KingJun 15, 2011
  15. Junio C HamanoJun 15, 2011
  16. Jeff KingJun 16, 2011
  17. Jakub NarebskiJun 16, 2011
  18. Junio C HamanoJun 8, 2011
  19. Ingo MolnarJun 8, 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.