Code

Merge branch 'bw/doc-repo-layout'
[git.git] / attr.c
diff --git a/attr.c b/attr.c
index 7f0f390d524a2d03595b742e720bd9b794089ee4..da29c8eb452af6a0a07829ab1ed2409c8aea5ef2 100644 (file)
--- a/attr.c
+++ b/attr.c
@@ -565,8 +565,7 @@ static void prepare_attr_stack(const char *path)
         * .gitattributes in deeper directories to shallower ones,
         * and finally use the built-in set as the default.
         */
-       if (!attr_stack)
-               bootstrap_attr_stack();
+       bootstrap_attr_stack();
 
        /*
         * Pop the "info" one that is always at the top of the stack.
@@ -713,20 +712,30 @@ static int macroexpand_one(int attr_nr, int rem)
        return rem;
 }
 
-int git_checkattr(const char *path, int num, struct git_attr_check *check)
+/*
+ * Collect all attributes for path into the array pointed to by
+ * check_all_attr.
+ */
+static void collect_all_attrs(const char *path)
 {
        struct attr_stack *stk;
-       int pathlen, i, rem;
+       int i, pathlen, rem;
 
-       bootstrap_attr_stack();
+       prepare_attr_stack(path);
        for (i = 0; i < attr_nr; i++)
                check_all_attr[i].value = ATTR__UNKNOWN;
 
        pathlen = strlen(path);
-       prepare_attr_stack(path);
        rem = attr_nr;
        for (stk = attr_stack; 0 < rem && stk; stk = stk->prev)
                rem = fill(path, pathlen, stk, rem);
+}
+
+int git_check_attr(const char *path, int num, struct git_attr_check *check)
+{
+       int i;
+
+       collect_all_attrs(path);
 
        for (i = 0; i < num; i++) {
                const char *value = check_all_attr[check[i].attr->attr_nr].value;
@@ -738,6 +747,34 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check)
        return 0;
 }
 
+int git_all_attrs(const char *path, int *num, struct git_attr_check **check)
+{
+       int i, count, j;
+
+       collect_all_attrs(path);
+
+       /* Count the number of attributes that are set. */
+       count = 0;
+       for (i = 0; i < attr_nr; i++) {
+               const char *value = check_all_attr[i].value;
+               if (value != ATTR__UNSET && value != ATTR__UNKNOWN)
+                       ++count;
+       }
+       *num = count;
+       *check = xmalloc(sizeof(**check) * count);
+       j = 0;
+       for (i = 0; i < attr_nr; i++) {
+               const char *value = check_all_attr[i].value;
+               if (value != ATTR__UNSET && value != ATTR__UNKNOWN) {
+                       (*check)[j].attr = check_all_attr[i].attr;
+                       (*check)[j].value = value;
+                       ++j;
+               }
+       }
+
+       return 0;
+}
+
 void git_attr_set_direction(enum git_attr_direction new, struct index_state *istate)
 {
        enum git_attr_direction old = direction;