From: Karthik Nayak <karthik.188@xxxxxxxxx> Add an option in 'filter_refs()' to use 'for_each_branch_ref()' and filter refs. This type checking is done by adding a 'FILTER_REFS_BRANCHES' in 'ref-filter.h'. Add an option in 'ref_filter_handler()' to filter different types of branches by calling 'filter_branch_kind()' which checks for the type of branch needed. Mentored-by: Christian Couder <christian.couder@xxxxxxxxx> Mentored-by: Matthieu Moy <matthieu.moy@xxxxxxxxxxxxxxx> Signed-off-by: Karthik Nayak <karthik.188@xxxxxxxxx> --- ref-filter.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ ref-filter.h | 10 ++++++++-- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/ref-filter.c b/ref-filter.c index 3ab4ab9..3f40144 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -1054,6 +1054,46 @@ static const unsigned char *match_points_at(struct sha1_array *points_at, return NULL; } +/* + * Checks if a given refname is a branch and returns the kind of + * branch it is. If not a branch, 0 is returned. + */ +static int filter_branch_kind(struct ref_filter *filter, const char *refname) +{ + int kind, i; + + static struct { + int kind; + const char *prefix; + } ref_kind[] = { + { REF_LOCAL_BRANCH, "refs/heads/" }, + { REF_REMOTE_BRANCH, "refs/remotes/" }, + }; + + /* If no kind is specified, no need to filter */ + if (!filter->branch_kind) + return REF_NO_BRANCH_FILTERING; + + for (i = 0; i < ARRAY_SIZE(ref_kind); i++) { + if (starts_with(refname, ref_kind[i].prefix)) { + kind = ref_kind[i].kind; + break; + } + } + + if (ARRAY_SIZE(ref_kind) <= i) { + if (!strcmp(refname, "HEAD")) + kind = REF_DETACHED_HEAD; + else + return 0; + } + + if ((filter->branch_kind & kind) == 0) + return 0; + + return kind; +} + /* Allocate space for a new ref_array_item and copy the objectname and flag to it */ static struct ref_array_item *new_ref_array_item(const char *refname, const unsigned char *objectname, @@ -1079,6 +1119,7 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid, struct ref_filter *filter = ref_cbdata->filter; struct ref_array_item *ref; struct commit *commit = NULL; + unsigned int kind; if (flag & REF_BAD_NAME) { warning("ignoring ref with broken name %s", refname); @@ -1090,6 +1131,9 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid, return 0; } + if (!(kind = filter_branch_kind(filter, refname))) + return 0; + if (!filter_pattern_match(filter, refname)) return 0; @@ -1118,6 +1162,7 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid, */ ref = new_ref_array_item(refname, oid->hash, flag); ref->commit = commit; + ref->kind = kind; REALLOC_ARRAY(ref_cbdata->array->items, ref_cbdata->array->nr + 1); ref_cbdata->array->items[ref_cbdata->array->nr++] = ref; @@ -1208,6 +1253,8 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int ret = for_each_ref(ref_filter_handler, &ref_cbdata); else if (type & FILTER_REFS_TAGS) ret = for_each_tag_ref_fullpath(ref_filter_handler, &ref_cbdata); + else if (type & FILTER_REFS_BRANCHES) + ret = for_each_rawref(ref_filter_handler, &ref_cbdata); else if (type) die("filter_refs: invalid type"); diff --git a/ref-filter.h b/ref-filter.h index 8c82fd1..a021b04 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -16,6 +16,12 @@ #define FILTER_REFS_INCLUDE_BROKEN 0x1 #define FILTER_REFS_ALL 0x2 #define FILTER_REFS_TAGS 0x4 +#define FILTER_REFS_BRANCHES 0x8 + +#define REF_DETACHED_HEAD 0x01 +#define REF_LOCAL_BRANCH 0x02 +#define REF_REMOTE_BRANCH 0x04 +#define REF_NO_BRANCH_FILTERING 0x08 struct atom_value { const char *s; @@ -40,7 +46,7 @@ struct ref_sorting { struct ref_array_item { unsigned char objectname[20]; - int flag; + int flag, kind; const char *symref; struct commit *commit; struct atom_value *value; @@ -66,7 +72,7 @@ struct ref_filter { unsigned int with_commit_tag_algo : 1, match_as_path : 1; - unsigned int lines; + unsigned int lines, branch_kind; }; struct ref_filter_cbdata { -- 2.4.6 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html