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>

Karthik Nayak committed Jun 14, 2015 at 01:07 UTC ed01e206ba53a52d0094abcd9f99237b4e2847c9
1 file changed +41 -23
builtin/for-each-ref.c
+41 -23
@@ -850,6 +850,44 @@ struct grab_ref_cbdata {
850 int grab_cnt;
851 };
852
853 +/*
854 + * Return 1 if the refname matches one of the patterns, otherwise 0.
855 + * A pattern can be path prefix (e.g. a refname "refs/heads/master"
856 + * matches a pattern "refs/heads/") or a wildcard (e.g. the same ref
857 + * matches "refs/heads/m*",too).
858 + */
859 +static int match_name_as_path(const char **pattern, const char *refname)
860 +{
861 + int namelen = strlen(refname);
862 + for (; *pattern; pattern++) {
863 + const char *p = *pattern;
864 + int plen = strlen(p);
865 +
866 + if ((plen <= namelen) &&
867 + !strncmp(refname, p, plen) &&
868 + (refname[plen] == '\0' ||
869 + refname[plen] == '/' ||
870 + p[plen-1] == '/'))
871 + return 1;
872 + if (!wildmatch(p, refname, WM_PATHNAME, NULL))
873 + return 1;
874 + }
875 + return 0;
876 +}
877 +
878 +/* Allocate space for a new refinfo and copy the objectname and flag to it */
879 +static struct refinfo *new_refinfo(const char *refname,
880 + const unsigned char *objectname,
881 + int flag)
882 +{
883 + struct refinfo *ref = xcalloc(1, sizeof(struct refinfo));
884 + ref->refname = xstrdup(refname);
885 + hashcpy(ref->objectname, objectname);
886 + ref->flag = flag;
887 +
888 + return ref;
889 +}
890 +
891 /*
892 * A call-back given to for_each_ref(). Filter refs and keep them for
893 * later object processing.
@@ -866,35 +904,15 @@ static int grab_single_ref(const char *refname, const struct object_id *oid,
904 return 0;
905 }
906
869 - if (*cb->grab_pattern) {
870 - const char **pattern;
871 - int namelen = strlen(refname);
872 - for (pattern = cb->grab_pattern; *pattern; pattern++) {
873 - const char *p = *pattern;
874 - int plen = strlen(p);
875 -
876 - if ((plen <= namelen) &&
877 - !strncmp(refname, p, plen) &&
878 - (refname[plen] == '\0' ||
879 - refname[plen] == '/' ||
880 - p[plen-1] == '/'))
881 - break;
882 - if (!wildmatch(p, refname, WM_PATHNAME, NULL))
883 - break;
884 - }
885 - if (!*pattern)
886 - return 0;
887 - }
907 + if (*cb->grab_pattern && !match_name_as_path(cb->grab_pattern, refname))
908 + return 0;
909
910 /*
911 * We do not open the object yet; sort may only need refname
912 * to do its job and the resulting list may yet to be pruned
913 * by maxcount logic.
914 */
894 - ref = xcalloc(1, sizeof(*ref));
895 - ref->refname = xstrdup(refname);
896 - hashcpy(ref->objectname, oid->hash);
897 - ref->flag = flag;
915 + ref = new_refinfo(refname, oid->hash, flag);
916
917 cnt = cb->grab_cnt;
918 REALLOC_ARRAY(cb->grab_array, cnt + 1);