On Tuesday 14 June 2011, Jeff King wrote: > On Tue, Jun 14, 2011 at 11:56:56AM +0200, Johan Herland wrote: > > 2. Interpreting/DWIMing refs > > > > Changing the ref mappings require a revised set of rules for > > interpreting shorthand ref names (expanding them into full ref names), > > and handling ambiguities when they arise: > > [...] > > > > - "origin/foo" must continue to work, even if "refs/remotes/origin/foo" > > has now become "refs/remotes/origin/heads/foo". In other words, > > "foo/bar" where "foo" is a valid remote, must try to resolve "bar" > > against the refspecs specified for the "foo" remote. > > 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. 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). (Obviously, all of the above assumes that "foo/bar/baz" does not match any local ref, which would take precedence over the remote-tracking refs listed above.) > I don't know offhand if "git remote" and "git clone" allow slashes in > remote names, but I don't think we forbid it if somebody configures it > themselves (and of course, remote names aside, they are free to write > whatever refspecs they like in the config file). git remote add foo/bar . does not report any errors for me. > > - If "refs/tags/foo" does not exist, tag name "foo" is unambiguous if > > it exists in one or more "refs/remotes/*/tags/foo" and they all point > > to the same SHA1. > > > > - If "refs/tags/foo" does not exist, and more than one > > "refs/remotes/*/tags/foo" exist, and they do NOT all point to the same > > SHA1, then there is an ambiguity. > > > > - The user may resolve the ambiguity by creating "refs/tags/foo" > > pointing to the chosen SHA1 ("refs/tags/foo" takes precedence over > > "refs/remotes/*/tags/foo"). > > > > - The same rules apply to heads, notes, etc. > > I'm not sure we need all of these rules for anything but tags. We > already keep remote heads in a separate namespace, and we don't > automagically look them up. And that's OK, because the way tags and > heads work is fundamentally different. I can peek at your remote heads, > but if I checkout or merge, I better make a local branch that matches > your remote one. Whereas with tags, I don't think that is the case. > They're really a read-only thing, and you want them to stay in the > remotes namespace. I don't really have any strong opinions here. As long as the rules end up being fairly intuitive and usable in practice, I'm quite happy to let others decide on the details. 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". Have fun! :) ...Johan -- Johan Herland, <johan@xxxxxxxxxxx> www.herland.net -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html