interpret_branch_name: allow callers to restrict expansions
The interpret_branch_name() function converts names like
@{-1} and @{upstream} into branch names. The expanded ref
names are not fully qualified, and may be outside of the
refs/heads/ namespace (e.g., "@" expands to "HEAD", and
"@{upstream}" is likely to be in "refs/remotes/").
This is OK for callers like dwim_ref() which are primarily
interested in resolving the resulting name, no matter where
it is. But callers like "git branch" treat the result as a
branch name in refs/heads/. When we expand to a ref outside
that namespace, the results are very confusing (e.g., "git
branch @" tries to create refs/heads/HEAD, which is
nonsense).
Callers can't know from the returned string how the
expansion happened (e.g., did the user really ask for a
branch named "HEAD", or did we do a bogus expansion?). One
fix would be to return some out-parameters describing the
types of expansion that occurred. This has the benefit that
the caller can generate precise error messages ("I
understood @{upstream} to mean origin/master, but that is a
remote tracking branch, so you cannot create it as a local
name").
However, out-parameters make the function interface somewhat
cumbersome. Instead, let's do the opposite: let the caller
tell us which elements to expand. That's easier to pass in,
and none of the callers give more precise error messages
than "@{upstream} isn't a valid branch name" anyway (which
should be sufficient).
The strbuf_branchname() function needs a similar parameter,
as most of the callers access interpret_branch_name()
through it.
We can break the callers down into two groups:
1. Callers that are happy with any kind of ref in the
result. We pass "0" here, so they continue to work
without restrictions. This includes merge_name(),
the reflog handling in add_pending_object_with_path(),
and substitute_branch_name(). This last is what powers
dwim_ref().
2. Callers that have funny corner cases (mostly in
git-branch and git-checkout). These need to make use of
the new parameter, but I've left them as "0" in this
patch, and will address them individually in follow-on
patches.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
0705fe202d
commit
0e9f62dab9
11
cache.h
11
cache.h
@ -1312,8 +1312,17 @@ extern char *oid_to_hex(const struct object_id *oid); /* same static buffer as s
|
||||
*
|
||||
* If the input was ok but there are not N branch switches in the
|
||||
* reflog, it returns 0.
|
||||
*
|
||||
* If "allowed" is non-zero, it is a treated as a bitfield of allowable
|
||||
* expansions: local branches ("refs/heads/"), remote branches
|
||||
* ("refs/remotes/"), or "HEAD". If no "allowed" bits are set, any expansion is
|
||||
* allowed, even ones to refs outside of those namespaces.
|
||||
*/
|
||||
extern int interpret_branch_name(const char *str, int len, struct strbuf *);
|
||||
#define INTERPRET_BRANCH_LOCAL (1<<0)
|
||||
#define INTERPRET_BRANCH_REMOTE (1<<1)
|
||||
#define INTERPRET_BRANCH_HEAD (1<<2)
|
||||
extern int interpret_branch_name(const char *str, int len, struct strbuf *,
|
||||
unsigned allowed);
|
||||
extern int get_oid_mb(const char *str, struct object_id *oid);
|
||||
|
||||
extern int validate_headref(const char *ref);
|
||||
|
||||
Reference in New Issue
Block a user