diff options
author | Steffen Prohaska <prohaska@zib.de> | 2007-11-11 17:01:46 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2007-11-19 05:39:00 +0300 |
commit | 79803322c1d8d2f74e1a53d44f363d878180e0f5 (patch) | |
tree | a0eab3ca833809dfd8f00893ca305de98038593c | |
parent | 47d996a20c3347bb9efbb44e8ed2d615cfdffba3 (diff) |
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>
-rw-r--r-- | cache.h | 3 | ||||
-rw-r--r-- | refs.c | 24 | ||||
-rw-r--r-- | sha1_name.c | 14 |
3 files changed, 29 insertions, 12 deletions
@@ -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); @@ -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) { diff --git a/sha1_name.c b/sha1_name.c index 2d727d54dc..d364244dc4 100644 --- a/sha1_name.c +++ b/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]; |