for-each-ref: extract helper functions out of grab_single_ref()

Extract two helper functions out of grab_single_ref(). Firstly,
new_refinfo() which is used to allocate memory for a new refinfo
structure and copy the objectname, refname and flag to it.
Secondly, match_name_as_path() which when given an array of patterns
and the refname checks if the refname matches any of the patterns
given while the pattern is a pathname, also supports wildcard
characters.

This is a preperatory patch for restructuring 'for-each-ref' and
eventually moving most of it to 'ref-filter' to provide the
functionality to similar commands via public API's.

Helped-by: Junio C Hamano <gitster@pobox.com>
Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Reviewed-by: Matthieu Moy <Matthieu.Moy@imag.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Karthik Nayak 2015-06-14 01:07:19 +05:30 коммит произвёл Junio C Hamano
Родитель a5fe66802f
Коммит ed01e206ba
1 изменённых файлов: 41 добавлений и 23 удалений

Просмотреть файл

@ -850,6 +850,44 @@ struct grab_ref_cbdata {
int grab_cnt;
};
/*
* Return 1 if the refname matches one of the patterns, otherwise 0.
* A pattern can be path prefix (e.g. a refname "refs/heads/master"
* matches a pattern "refs/heads/") or a wildcard (e.g. the same ref
* matches "refs/heads/m*",too).
*/
static int match_name_as_path(const char **pattern, const char *refname)
{
int namelen = strlen(refname);
for (; *pattern; pattern++) {
const char *p = *pattern;
int plen = strlen(p);
if ((plen <= namelen) &&
!strncmp(refname, p, plen) &&
(refname[plen] == '\0' ||
refname[plen] == '/' ||
p[plen-1] == '/'))
return 1;
if (!wildmatch(p, refname, WM_PATHNAME, NULL))
return 1;
}
return 0;
}
/* Allocate space for a new refinfo and copy the objectname and flag to it */
static struct refinfo *new_refinfo(const char *refname,
const unsigned char *objectname,
int flag)
{
struct refinfo *ref = xcalloc(1, sizeof(struct refinfo));
ref->refname = xstrdup(refname);
hashcpy(ref->objectname, objectname);
ref->flag = flag;
return ref;
}
/*
* A call-back given to for_each_ref(). Filter refs and keep them for
* later object processing.
@ -866,35 +904,15 @@ static int grab_single_ref(const char *refname, const struct object_id *oid,
return 0;
}
if (*cb->grab_pattern) {
const char **pattern;
int namelen = strlen(refname);
for (pattern = cb->grab_pattern; *pattern; pattern++) {
const char *p = *pattern;
int plen = strlen(p);
if ((plen <= namelen) &&
!strncmp(refname, p, plen) &&
(refname[plen] == '\0' ||
refname[plen] == '/' ||
p[plen-1] == '/'))
break;
if (!wildmatch(p, refname, WM_PATHNAME, NULL))
break;
}
if (!*pattern)
return 0;
}
if (*cb->grab_pattern && !match_name_as_path(cb->grab_pattern, refname))
return 0;
/*
* We do not open the object yet; sort may only need refname
* to do its job and the resulting list may yet to be pruned
* by maxcount logic.
*/
ref = xcalloc(1, sizeof(*ref));
ref->refname = xstrdup(refname);
hashcpy(ref->objectname, oid->hash);
ref->flag = flag;
ref = new_refinfo(refname, oid->hash, flag);
cnt = cb->grab_cnt;
REALLOC_ARRAY(cb->grab_array, cnt + 1);