add refname_match()
We use at least two rulesets for matching abbreviated refnames with
full refnames (starting with 'refs/'). git-rev-parse and git-fetch
use slightly different rules.
This commit introduces a new function refname_match
(const char *abbrev_name, const char *full_name, const char **rules).
abbrev_name is expanded using the rules and matched against full_name.
If a match is found the function returns true. rules is a NULL-terminate
list of format patterns with "%.*s", for example:
const char *ref_rev_parse_rules[] = {
"%.*s",
"refs/%.*s",
"refs/tags/%.*s",
"refs/heads/%.*s",
"refs/remotes/%.*s",
"refs/remotes/%.*s/HEAD",
NULL
};
Asterisks are included in the format strings because this is the form
required in sha1_name.c. Sharing the list with the functions there is
a good idea to avoid duplicating the rules. Hopefully this
facilitates unified matching rules in the future.
This commit makes the rules used by rev-parse for resolving refs to
sha1s available for string comparison. Before this change, the rules
were buried in get_sha1*() and dwim_ref().
A follow-up commit will refactor the rules used by fetch.
refname_match() will be used for matching refspecs in git-send-pack.
Thanks to Daniel Barkalow <barkalow@iabervon.org> for pointing
out that ref_matches_abbrev in remote.c solves a similar problem
and care should be taken to avoid confusion.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
parent
47d996a20c
commit
79803322c1
3
cache.h
3
cache.h
|
|
@ -415,6 +415,9 @@ extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *
|
|||
extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref);
|
||||
extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref);
|
||||
|
||||
extern int refname_match(const char *abbrev_name, const char *full_name, const char **rules);
|
||||
extern const char *ref_rev_parse_rules[];
|
||||
|
||||
extern int create_symref(const char *ref, const char *refs_heads_master, const char *logmsg);
|
||||
extern int validate_headref(const char *ref);
|
||||
|
||||
|
|
|
|||
24
refs.c
24
refs.c
|
|
@ -643,6 +643,30 @@ int check_ref_format(const char *ref)
|
|||
}
|
||||
}
|
||||
|
||||
const char *ref_rev_parse_rules[] = {
|
||||
"%.*s",
|
||||
"refs/%.*s",
|
||||
"refs/tags/%.*s",
|
||||
"refs/heads/%.*s",
|
||||
"refs/remotes/%.*s",
|
||||
"refs/remotes/%.*s/HEAD",
|
||||
NULL
|
||||
};
|
||||
|
||||
int refname_match(const char *abbrev_name, const char *full_name, const char **rules)
|
||||
{
|
||||
const char **p;
|
||||
const int abbrev_name_len = strlen(abbrev_name);
|
||||
|
||||
for (p = rules; *p; p++) {
|
||||
if (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ref_lock *verify_lock(struct ref_lock *lock,
|
||||
const unsigned char *old_sha1, int mustexist)
|
||||
{
|
||||
|
|
|
|||
14
sha1_name.c
14
sha1_name.c
|
|
@ -239,23 +239,13 @@ static int ambiguous_path(const char *path, int len)
|
|||
return slash;
|
||||
}
|
||||
|
||||
static const char *ref_fmt[] = {
|
||||
"%.*s",
|
||||
"refs/%.*s",
|
||||
"refs/tags/%.*s",
|
||||
"refs/heads/%.*s",
|
||||
"refs/remotes/%.*s",
|
||||
"refs/remotes/%.*s/HEAD",
|
||||
NULL
|
||||
};
|
||||
|
||||
int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
|
||||
{
|
||||
const char **p, *r;
|
||||
int refs_found = 0;
|
||||
|
||||
*ref = NULL;
|
||||
for (p = ref_fmt; *p; p++) {
|
||||
for (p = ref_rev_parse_rules; *p; p++) {
|
||||
unsigned char sha1_from_ref[20];
|
||||
unsigned char *this_result;
|
||||
|
||||
|
|
@ -277,7 +267,7 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
|
|||
int logs_found = 0;
|
||||
|
||||
*log = NULL;
|
||||
for (p = ref_fmt; *p; p++) {
|
||||
for (p = ref_rev_parse_rules; *p; p++) {
|
||||
struct stat st;
|
||||
unsigned char hash[20];
|
||||
char path[PATH_MAX];
|
||||
|
|
|
|||
Loading…
Reference in New Issue