The "$remote/$branch" syntax can be interpreted in two subtly different

 1. A shorthand name for the remote-tracking branch corresponding to a
    specific $branch from a specific $remote.

 2. A refname fragment, which - when appended to "refs/remotes/" -
    yields the remote-tracking branch corresponding to a specific
    $branch from a specific $remote.

For the current default/conventional refspecs, both interpretations are
true and equally valid. However, when configuring non-default refspecs
(such as the +refs/heads/*:refs/remotes/origin/heads/*), it becomes
obvious that the current code follows the latter interpretation: The
"$remote/$branch" shorthand will no longer work, and you are forced to
use "$remote/heads/$branch" instead.

I argue that the former interpretation is what most users intuitively
expect, and that we should work towards making Git follow the same

Instead of prepending "refs/remotes/" to convert "$remote/$branch" into
a full refname, we should find "$remote" in the repo config, and then
map "refs/heads/$branch" through $remote's fetch refspec(s), to find
the remote-tracking branch that properly corresponds to the specific
$branch in the $remote repo.

This goal is achieved by the final patch in this series, and most of
the preceding patches serve as preliminary changes and refactoring to
support this.

Patch #1 is the exception in that it is a self-contained bugfix for a
scanf-related problem I ran across while working on the patch series.

Patches #2 and #3 introduce a new test intended to verify Git's
usability when working with remote ref namespaces (which rely on
setting up unconventional refspecs). For now, this test is fairly
thin, but it should be expanded as we find more problems with these
kinds of setups.

Patches #4 and #5 are pure refactorings to reorganize the code that
expands shorthand names to full refnames and vice versa. The idea
is to associate the patterns that are used to expand/shorten ref
names with the actual function that does the expansion/shortening,
so that we can later add patterns that uses different expand/shorten

Patch #6 teaches Git to realize when - in the context of communication
with a remote repo - it's expanding shorthand refs into either local
refnames, or remote refnames. It is important that any expansion rules
relying on local repo configuration are not allowed to expand shorthand
names on behalf of the remote repo.

Finally, patch #7 introduces a new rule and associated expand/shorten
functions mapping "$remote/$branch"-type shorthand names to/from their
remote-tracking branch counterparts, by using the configured refspecs
as described above. This rule is obviously only applied to local refs,
as it would be wrong for a repo to use its local config to dictate a
ref expansion in a remote repo.

The series has been build on recent 'next', and although it also
applies cleanly to v1.8.3-rc1, it will cause a test failure in
t7900, since it depends on the jh/checkout-auto-tracking topic, which
is currently cooking.

Have fun! :)


Johan Herland (7):
  shorten_unambiguous_ref(): Allow shortening refs/remotes/origin/HEAD to origin
  t7900: Start testing usability of namespaced remote refs
  t7900: Demonstrate failure to expand "$remote/$branch" according to refspecs
  refs.c: Refactor rules for expanding shorthand names into full refnames
  refs.c: Refactor code for shortening full refnames into shorthand names
  refname_match(): Caller must declare if we're matching local or remote refs
  refs.c: Add rules for resolving refs using remote refspecs

 cache.h                                        |   4 -
 refs.c                                         | 260 +++++++++++++++++--------
 refs.h                                         |  14 ++
 remote.c                                       |  15 +-
 t/                        |  12 ++
 t/ | 133 +++++++++++++
 6 files changed, 342 insertions(+), 96 deletions(-)
 create mode 100755 t/


To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to
More majordomo info at

Reply via email to