e008f302607cc1dcd9d24d7914349e139593cd91
1/*
2 * Handle git attributes. See gitattributes(5) for a description of
3 * the file syntax, and Documentation/technical/api-gitattributes.txt
4 * for a description of the API.
5 *
6 * One basic design decision here is that we are not going to support
7 * an insanely large number of attributes.
8 */
9
10#define NO_THE_INDEX_COMPATIBILITY_MACROS
11#include "cache.h"
12#include "exec_cmd.h"
13#include "attr.h"
14#include "dir.h"
15#include "utf8.h"
16#include "quote.h"
17#include "thread-utils.h"
18
19const char git_attr__true[] = "(builtin)true";
20const char git_attr__false[] = "\0(builtin)false";
21static const char git_attr__unknown[] = "(builtin)unknown";
22#define ATTR__TRUE git_attr__true
23#define ATTR__FALSE git_attr__false
24#define ATTR__UNSET NULL
25#define ATTR__UNKNOWN git_attr__unknown
26
27#ifndef DEBUG_ATTR
28#define DEBUG_ATTR 0
29#endif
30
31struct git_attr {
32 int attr_nr; /* unique attribute number */
33 int maybe_macro;
34 int maybe_real;
35 char name[FLEX_ARRAY]; /* attribute name */
36};
37static int attr_nr;
38
39/*
40 * NEEDSWORK: maybe-real, maybe-macro are not property of
41 * an attribute, as it depends on what .gitattributes are
42 * read. Once we introduce per git_attr_check attr_stack
43 * and check_all_attr, the optimization based on them will
44 * become unnecessary and can go away. So is this variable.
45 */
46static int cannot_trust_maybe_real;
47
48/* NEEDSWORK: This will become per git_attr_check */
49static struct attr_check_item *check_all_attr;
50
51const char *git_attr_name(const struct git_attr *attr)
52{
53 return attr->name;
54}
55
56struct attr_hashmap {
57 struct hashmap map;
58#ifndef NO_PTHREADS
59 pthread_mutex_t mutex;
60#endif
61};
62
63static inline void hashmap_lock(struct attr_hashmap *map)
64{
65#ifndef NO_PTHREADS
66 pthread_mutex_lock(&map->mutex);
67#endif
68}
69
70static inline void hashmap_unlock(struct attr_hashmap *map)
71{
72#ifndef NO_PTHREADS
73 pthread_mutex_unlock(&map->mutex);
74#endif
75}
76
77/*
78 * The global dictionary of all interned attributes. This
79 * is a singleton object which is shared between threads.
80 * Access to this dictionary must be surrounded with a mutex.
81 */
82static struct attr_hashmap g_attr_hashmap;
83
84/* The container for objects stored in "struct attr_hashmap" */
85struct attr_hash_entry {
86 struct hashmap_entry ent; /* must be the first member! */
87 const char *key; /* the key; memory should be owned by value */
88 size_t keylen; /* length of the key */
89 void *value; /* the stored value */
90};
91
92/* attr_hashmap comparison function */
93static int attr_hash_entry_cmp(const struct attr_hash_entry *a,
94 const struct attr_hash_entry *b,
95 void *unused)
96{
97 return (a->keylen != b->keylen) || strncmp(a->key, b->key, a->keylen);
98}
99
100/* Initialize an 'attr_hashmap' object */
101static void attr_hashmap_init(struct attr_hashmap *map)
102{
103 hashmap_init(&map->map, (hashmap_cmp_fn) attr_hash_entry_cmp, 0);
104}
105
106/*
107 * Retrieve the 'value' stored in a hashmap given the provided 'key'.
108 * If there is no matching entry, return NULL.
109 */
110static void *attr_hashmap_get(struct attr_hashmap *map,
111 const char *key, size_t keylen)
112{
113 struct attr_hash_entry k;
114 struct attr_hash_entry *e;
115
116 if (!map->map.tablesize)
117 attr_hashmap_init(map);
118
119 hashmap_entry_init(&k, memhash(key, keylen));
120 k.key = key;
121 k.keylen = keylen;
122 e = hashmap_get(&map->map, &k, NULL);
123
124 return e ? e->value : NULL;
125}
126
127/* Add 'value' to a hashmap based on the provided 'key'. */
128static void attr_hashmap_add(struct attr_hashmap *map,
129 const char *key, size_t keylen,
130 void *value)
131{
132 struct attr_hash_entry *e;
133
134 if (!map->map.tablesize)
135 attr_hashmap_init(map);
136
137 e = xmalloc(sizeof(struct attr_hash_entry));
138 hashmap_entry_init(e, memhash(key, keylen));
139 e->key = key;
140 e->keylen = keylen;
141 e->value = value;
142
143 hashmap_add(&map->map, e);
144}
145
146static int attr_name_valid(const char *name, size_t namelen)
147{
148 /*
149 * Attribute name cannot begin with '-' and must consist of
150 * characters from [-A-Za-z0-9_.].
151 */
152 if (namelen <= 0 || *name == '-')
153 return 0;
154 while (namelen--) {
155 char ch = *name++;
156 if (! (ch == '-' || ch == '.' || ch == '_' ||
157 ('0' <= ch && ch <= '9') ||
158 ('a' <= ch && ch <= 'z') ||
159 ('A' <= ch && ch <= 'Z')) )
160 return 0;
161 }
162 return 1;
163}
164
165static void report_invalid_attr(const char *name, size_t len,
166 const char *src, int lineno)
167{
168 struct strbuf err = STRBUF_INIT;
169 strbuf_addf(&err, _("%.*s is not a valid attribute name"),
170 (int) len, name);
171 fprintf(stderr, "%s: %s:%d\n", err.buf, src, lineno);
172 strbuf_release(&err);
173}
174
175/*
176 * Given a 'name', lookup and return the corresponding attribute in the global
177 * dictionary. If no entry is found, create a new attribute and store it in
178 * the dictionary.
179 */
180static struct git_attr *git_attr_internal(const char *name, int namelen)
181{
182 struct git_attr *a;
183
184 if (!attr_name_valid(name, namelen))
185 return NULL;
186
187 hashmap_lock(&g_attr_hashmap);
188
189 a = attr_hashmap_get(&g_attr_hashmap, name, namelen);
190
191 if (!a) {
192 FLEX_ALLOC_MEM(a, name, name, namelen);
193 a->attr_nr = g_attr_hashmap.map.size;
194 a->maybe_real = 0;
195 a->maybe_macro = 0;
196
197 attr_hashmap_add(&g_attr_hashmap, a->name, namelen, a);
198 assert(a->attr_nr == (g_attr_hashmap.map.size - 1));
199
200 /*
201 * NEEDSWORK: per git_attr_check check_all_attr
202 * will be initialized a lot more lazily, not
203 * like this, and not here.
204 */
205 REALLOC_ARRAY(check_all_attr, ++attr_nr);
206 check_all_attr[a->attr_nr].attr = a;
207 check_all_attr[a->attr_nr].value = ATTR__UNKNOWN;
208 assert(a->attr_nr == (attr_nr - 1));
209 }
210
211 hashmap_unlock(&g_attr_hashmap);
212
213 return a;
214}
215
216struct git_attr *git_attr(const char *name)
217{
218 return git_attr_internal(name, strlen(name));
219}
220
221/* What does a matched pattern decide? */
222struct attr_state {
223 struct git_attr *attr;
224 const char *setto;
225};
226
227struct pattern {
228 const char *pattern;
229 int patternlen;
230 int nowildcardlen;
231 unsigned flags; /* EXC_FLAG_* */
232};
233
234/*
235 * One rule, as from a .gitattributes file.
236 *
237 * If is_macro is true, then u.attr is a pointer to the git_attr being
238 * defined.
239 *
240 * If is_macro is false, then u.pat is the filename pattern to which the
241 * rule applies.
242 *
243 * In either case, num_attr is the number of attributes affected by
244 * this rule, and state is an array listing them. The attributes are
245 * listed as they appear in the file (macros unexpanded).
246 */
247struct match_attr {
248 union {
249 struct pattern pat;
250 struct git_attr *attr;
251 } u;
252 char is_macro;
253 unsigned num_attr;
254 struct attr_state state[FLEX_ARRAY];
255};
256
257static const char blank[] = " \t\r\n";
258
259/*
260 * Parse a whitespace-delimited attribute state (i.e., "attr",
261 * "-attr", "!attr", or "attr=value") from the string starting at src.
262 * If e is not NULL, write the results to *e. Return a pointer to the
263 * remainder of the string (with leading whitespace removed), or NULL
264 * if there was an error.
265 */
266static const char *parse_attr(const char *src, int lineno, const char *cp,
267 struct attr_state *e)
268{
269 const char *ep, *equals;
270 int len;
271
272 ep = cp + strcspn(cp, blank);
273 equals = strchr(cp, '=');
274 if (equals && ep < equals)
275 equals = NULL;
276 if (equals)
277 len = equals - cp;
278 else
279 len = ep - cp;
280 if (!e) {
281 if (*cp == '-' || *cp == '!') {
282 cp++;
283 len--;
284 }
285 if (!attr_name_valid(cp, len)) {
286 report_invalid_attr(cp, len, src, lineno);
287 return NULL;
288 }
289 } else {
290 /*
291 * As this function is always called twice, once with
292 * e == NULL in the first pass and then e != NULL in
293 * the second pass, no need for attr_name_valid()
294 * check here.
295 */
296 if (*cp == '-' || *cp == '!') {
297 e->setto = (*cp == '-') ? ATTR__FALSE : ATTR__UNSET;
298 cp++;
299 len--;
300 }
301 else if (!equals)
302 e->setto = ATTR__TRUE;
303 else {
304 e->setto = xmemdupz(equals + 1, ep - equals - 1);
305 }
306 e->attr = git_attr_internal(cp, len);
307 }
308 return ep + strspn(ep, blank);
309}
310
311static struct match_attr *parse_attr_line(const char *line, const char *src,
312 int lineno, int macro_ok)
313{
314 int namelen;
315 int num_attr, i;
316 const char *cp, *name, *states;
317 struct match_attr *res = NULL;
318 int is_macro;
319 struct strbuf pattern = STRBUF_INIT;
320
321 cp = line + strspn(line, blank);
322 if (!*cp || *cp == '#')
323 return NULL;
324 name = cp;
325
326 if (*cp == '"' && !unquote_c_style(&pattern, name, &states)) {
327 name = pattern.buf;
328 namelen = pattern.len;
329 } else {
330 namelen = strcspn(name, blank);
331 states = name + namelen;
332 }
333
334 if (strlen(ATTRIBUTE_MACRO_PREFIX) < namelen &&
335 starts_with(name, ATTRIBUTE_MACRO_PREFIX)) {
336 if (!macro_ok) {
337 fprintf(stderr, "%s not allowed: %s:%d\n",
338 name, src, lineno);
339 goto fail_return;
340 }
341 is_macro = 1;
342 name += strlen(ATTRIBUTE_MACRO_PREFIX);
343 name += strspn(name, blank);
344 namelen = strcspn(name, blank);
345 if (!attr_name_valid(name, namelen)) {
346 report_invalid_attr(name, namelen, src, lineno);
347 goto fail_return;
348 }
349 }
350 else
351 is_macro = 0;
352
353 states += strspn(states, blank);
354
355 /* First pass to count the attr_states */
356 for (cp = states, num_attr = 0; *cp; num_attr++) {
357 cp = parse_attr(src, lineno, cp, NULL);
358 if (!cp)
359 goto fail_return;
360 }
361
362 res = xcalloc(1,
363 sizeof(*res) +
364 sizeof(struct attr_state) * num_attr +
365 (is_macro ? 0 : namelen + 1));
366 if (is_macro) {
367 res->u.attr = git_attr_internal(name, namelen);
368 res->u.attr->maybe_macro = 1;
369 } else {
370 char *p = (char *)&(res->state[num_attr]);
371 memcpy(p, name, namelen);
372 res->u.pat.pattern = p;
373 parse_exclude_pattern(&res->u.pat.pattern,
374 &res->u.pat.patternlen,
375 &res->u.pat.flags,
376 &res->u.pat.nowildcardlen);
377 if (res->u.pat.flags & EXC_FLAG_NEGATIVE) {
378 warning(_("Negative patterns are ignored in git attributes\n"
379 "Use '\\!' for literal leading exclamation."));
380 goto fail_return;
381 }
382 }
383 res->is_macro = is_macro;
384 res->num_attr = num_attr;
385
386 /* Second pass to fill the attr_states */
387 for (cp = states, i = 0; *cp; i++) {
388 cp = parse_attr(src, lineno, cp, &(res->state[i]));
389 if (!is_macro)
390 res->state[i].attr->maybe_real = 1;
391 if (res->state[i].attr->maybe_macro)
392 cannot_trust_maybe_real = 1;
393 }
394
395 strbuf_release(&pattern);
396 return res;
397
398fail_return:
399 strbuf_release(&pattern);
400 free(res);
401 return NULL;
402}
403
404/*
405 * Like info/exclude and .gitignore, the attribute information can
406 * come from many places.
407 *
408 * (1) .gitattribute file of the same directory;
409 * (2) .gitattribute file of the parent directory if (1) does not have
410 * any match; this goes recursively upwards, just like .gitignore.
411 * (3) $GIT_DIR/info/attributes, which overrides both of the above.
412 *
413 * In the same file, later entries override the earlier match, so in the
414 * global list, we would have entries from info/attributes the earliest
415 * (reading the file from top to bottom), .gitattribute of the root
416 * directory (again, reading the file from top to bottom) down to the
417 * current directory, and then scan the list backwards to find the first match.
418 * This is exactly the same as what is_excluded() does in dir.c to deal with
419 * .gitignore file and info/excludes file as a fallback.
420 */
421
422/* NEEDSWORK: This will become per git_attr_check */
423static struct attr_stack {
424 struct attr_stack *prev;
425 char *origin;
426 size_t originlen;
427 unsigned num_matches;
428 unsigned alloc;
429 struct match_attr **attrs;
430} *attr_stack;
431
432static void free_attr_elem(struct attr_stack *e)
433{
434 int i;
435 free(e->origin);
436 for (i = 0; i < e->num_matches; i++) {
437 struct match_attr *a = e->attrs[i];
438 int j;
439 for (j = 0; j < a->num_attr; j++) {
440 const char *setto = a->state[j].setto;
441 if (setto == ATTR__TRUE ||
442 setto == ATTR__FALSE ||
443 setto == ATTR__UNSET ||
444 setto == ATTR__UNKNOWN)
445 ;
446 else
447 free((char *) setto);
448 }
449 free(a);
450 }
451 free(e->attrs);
452 free(e);
453}
454
455struct attr_check *attr_check_alloc(void)
456{
457 return xcalloc(1, sizeof(struct attr_check));
458}
459
460struct attr_check *attr_check_initl(const char *one, ...)
461{
462 struct attr_check *check;
463 int cnt;
464 va_list params;
465 const char *param;
466
467 va_start(params, one);
468 for (cnt = 1; (param = va_arg(params, const char *)) != NULL; cnt++)
469 ;
470 va_end(params);
471
472 check = attr_check_alloc();
473 check->nr = cnt;
474 check->alloc = cnt;
475 check->items = xcalloc(cnt, sizeof(struct attr_check_item));
476
477 check->items[0].attr = git_attr(one);
478 va_start(params, one);
479 for (cnt = 1; cnt < check->nr; cnt++) {
480 const struct git_attr *attr;
481 param = va_arg(params, const char *);
482 if (!param)
483 die("BUG: counted %d != ended at %d",
484 check->nr, cnt);
485 attr = git_attr(param);
486 if (!attr)
487 die("BUG: %s: not a valid attribute name", param);
488 check->items[cnt].attr = attr;
489 }
490 va_end(params);
491 return check;
492}
493
494struct attr_check_item *attr_check_append(struct attr_check *check,
495 const struct git_attr *attr)
496{
497 struct attr_check_item *item;
498
499 ALLOC_GROW(check->items, check->nr + 1, check->alloc);
500 item = &check->items[check->nr++];
501 item->attr = attr;
502 return item;
503}
504
505void attr_check_reset(struct attr_check *check)
506{
507 check->nr = 0;
508}
509
510void attr_check_clear(struct attr_check *check)
511{
512 free(check->items);
513 check->items = NULL;
514 check->alloc = 0;
515 check->nr = 0;
516}
517
518void attr_check_free(struct attr_check *check)
519{
520 attr_check_clear(check);
521 free(check);
522}
523
524static const char *builtin_attr[] = {
525 "[attr]binary -diff -merge -text",
526 NULL,
527};
528
529static void handle_attr_line(struct attr_stack *res,
530 const char *line,
531 const char *src,
532 int lineno,
533 int macro_ok)
534{
535 struct match_attr *a;
536
537 a = parse_attr_line(line, src, lineno, macro_ok);
538 if (!a)
539 return;
540 ALLOC_GROW(res->attrs, res->num_matches + 1, res->alloc);
541 res->attrs[res->num_matches++] = a;
542}
543
544static struct attr_stack *read_attr_from_array(const char **list)
545{
546 struct attr_stack *res;
547 const char *line;
548 int lineno = 0;
549
550 res = xcalloc(1, sizeof(*res));
551 while ((line = *(list++)) != NULL)
552 handle_attr_line(res, line, "[builtin]", ++lineno, 1);
553 return res;
554}
555
556/*
557 * NEEDSWORK: these two are tricky. The callers assume there is a
558 * single, system-wide global state "where we read attributes from?"
559 * and when the state is flipped by calling git_attr_set_direction(),
560 * attr_stack is discarded so that subsequent attr_check will lazily
561 * read from the right place. And they do not know or care who called
562 * by them uses the attribute subsystem, hence have no knowledge of
563 * existing git_attr_check instances or future ones that will be
564 * created).
565 *
566 * Probably we need a thread_local that holds these two variables,
567 * and a list of git_attr_check instances (which need to be maintained
568 * by hooking into git_attr_check_alloc(), git_attr_check_initl(), and
569 * git_attr_check_clear(). Then git_attr_set_direction() updates the
570 * fields in that thread_local for these two variables, iterate over
571 * all the active git_attr_check instances and discard the attr_stack
572 * they hold. Yuck, but it sounds doable.
573 */
574static enum git_attr_direction direction;
575static struct index_state *use_index;
576
577static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)
578{
579 FILE *fp = fopen(path, "r");
580 struct attr_stack *res;
581 char buf[2048];
582 int lineno = 0;
583
584 if (!fp) {
585 if (errno != ENOENT && errno != ENOTDIR)
586 warn_on_inaccessible(path);
587 return NULL;
588 }
589 res = xcalloc(1, sizeof(*res));
590 while (fgets(buf, sizeof(buf), fp)) {
591 char *bufp = buf;
592 if (!lineno)
593 skip_utf8_bom(&bufp, strlen(bufp));
594 handle_attr_line(res, bufp, path, ++lineno, macro_ok);
595 }
596 fclose(fp);
597 return res;
598}
599
600static struct attr_stack *read_attr_from_index(const char *path, int macro_ok)
601{
602 struct attr_stack *res;
603 char *buf, *sp;
604 int lineno = 0;
605
606 buf = read_blob_data_from_index(use_index ? use_index : &the_index, path, NULL);
607 if (!buf)
608 return NULL;
609
610 res = xcalloc(1, sizeof(*res));
611 for (sp = buf; *sp; ) {
612 char *ep;
613 int more;
614
615 ep = strchrnul(sp, '\n');
616 more = (*ep == '\n');
617 *ep = '\0';
618 handle_attr_line(res, sp, path, ++lineno, macro_ok);
619 sp = ep + more;
620 }
621 free(buf);
622 return res;
623}
624
625static struct attr_stack *read_attr(const char *path, int macro_ok)
626{
627 struct attr_stack *res;
628
629 if (direction == GIT_ATTR_CHECKOUT) {
630 res = read_attr_from_index(path, macro_ok);
631 if (!res)
632 res = read_attr_from_file(path, macro_ok);
633 }
634 else if (direction == GIT_ATTR_CHECKIN) {
635 res = read_attr_from_file(path, macro_ok);
636 if (!res)
637 /*
638 * There is no checked out .gitattributes file there, but
639 * we might have it in the index. We allow operation in a
640 * sparsely checked out work tree, so read from it.
641 */
642 res = read_attr_from_index(path, macro_ok);
643 }
644 else
645 res = read_attr_from_index(path, macro_ok);
646 if (!res)
647 res = xcalloc(1, sizeof(*res));
648 return res;
649}
650
651#if DEBUG_ATTR
652static void debug_info(const char *what, struct attr_stack *elem)
653{
654 fprintf(stderr, "%s: %s\n", what, elem->origin ? elem->origin : "()");
655}
656static void debug_set(const char *what, const char *match, struct git_attr *attr, const void *v)
657{
658 const char *value = v;
659
660 if (ATTR_TRUE(value))
661 value = "set";
662 else if (ATTR_FALSE(value))
663 value = "unset";
664 else if (ATTR_UNSET(value))
665 value = "unspecified";
666
667 fprintf(stderr, "%s: %s => %s (%s)\n",
668 what, attr->name, (char *) value, match);
669}
670#define debug_push(a) debug_info("push", (a))
671#define debug_pop(a) debug_info("pop", (a))
672#else
673#define debug_push(a) do { ; } while (0)
674#define debug_pop(a) do { ; } while (0)
675#define debug_set(a,b,c,d) do { ; } while (0)
676#endif /* DEBUG_ATTR */
677
678static void drop_attr_stack(void)
679{
680 while (attr_stack) {
681 struct attr_stack *elem = attr_stack;
682 attr_stack = elem->prev;
683 free_attr_elem(elem);
684 }
685}
686
687static const char *git_etc_gitattributes(void)
688{
689 static const char *system_wide;
690 if (!system_wide)
691 system_wide = system_path(ETC_GITATTRIBUTES);
692 return system_wide;
693}
694
695static int git_attr_system(void)
696{
697 return !git_env_bool("GIT_ATTR_NOSYSTEM", 0);
698}
699
700static GIT_PATH_FUNC(git_path_info_attributes, INFOATTRIBUTES_FILE)
701
702static void push_stack(struct attr_stack **attr_stack_p,
703 struct attr_stack *elem, char *origin, size_t originlen)
704{
705 if (elem) {
706 elem->origin = origin;
707 if (origin)
708 elem->originlen = originlen;
709 elem->prev = *attr_stack_p;
710 *attr_stack_p = elem;
711 }
712}
713
714static void bootstrap_attr_stack(void)
715{
716 struct attr_stack *elem;
717
718 if (attr_stack)
719 return;
720
721 push_stack(&attr_stack, read_attr_from_array(builtin_attr), NULL, 0);
722
723 if (git_attr_system())
724 push_stack(&attr_stack,
725 read_attr_from_file(git_etc_gitattributes(), 1),
726 NULL, 0);
727
728 if (!git_attributes_file)
729 git_attributes_file = xdg_config_home("attributes");
730 if (git_attributes_file)
731 push_stack(&attr_stack,
732 read_attr_from_file(git_attributes_file, 1),
733 NULL, 0);
734
735 if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
736 elem = read_attr(GITATTRIBUTES_FILE, 1);
737 push_stack(&attr_stack, elem, xstrdup(""), 0);
738 debug_push(elem);
739 }
740
741 if (startup_info->have_repository)
742 elem = read_attr_from_file(git_path_info_attributes(), 1);
743 else
744 elem = NULL;
745
746 if (!elem)
747 elem = xcalloc(1, sizeof(*elem));
748 push_stack(&attr_stack, elem, NULL, 0);
749}
750
751static void prepare_attr_stack(const char *path, int dirlen)
752{
753 struct attr_stack *elem, *info;
754 const char *cp;
755
756 /*
757 * At the bottom of the attribute stack is the built-in
758 * set of attribute definitions, followed by the contents
759 * of $(prefix)/etc/gitattributes and a file specified by
760 * core.attributesfile. Then, contents from
761 * .gitattribute files from directories closer to the
762 * root to the ones in deeper directories are pushed
763 * to the stack. Finally, at the very top of the stack
764 * we always keep the contents of $GIT_DIR/info/attributes.
765 *
766 * When checking, we use entries from near the top of the
767 * stack, preferring $GIT_DIR/info/attributes, then
768 * .gitattributes in deeper directories to shallower ones,
769 * and finally use the built-in set as the default.
770 */
771 bootstrap_attr_stack();
772
773 /*
774 * Pop the "info" one that is always at the top of the stack.
775 */
776 info = attr_stack;
777 attr_stack = info->prev;
778
779 /*
780 * Pop the ones from directories that are not the prefix of
781 * the path we are checking. Break out of the loop when we see
782 * the root one (whose origin is an empty string "") or the builtin
783 * one (whose origin is NULL) without popping it.
784 */
785 while (attr_stack->origin) {
786 int namelen = strlen(attr_stack->origin);
787
788 elem = attr_stack;
789 if (namelen <= dirlen &&
790 !strncmp(elem->origin, path, namelen) &&
791 (!namelen || path[namelen] == '/'))
792 break;
793
794 debug_pop(elem);
795 attr_stack = elem->prev;
796 free_attr_elem(elem);
797 }
798
799 /*
800 * Read from parent directories and push them down
801 */
802 if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
803 /*
804 * bootstrap_attr_stack() should have added, and the
805 * above loop should have stopped before popping, the
806 * root element whose attr_stack->origin is set to an
807 * empty string.
808 */
809 struct strbuf pathbuf = STRBUF_INIT;
810
811 assert(attr_stack->origin);
812 while (1) {
813 size_t len = strlen(attr_stack->origin);
814 char *origin;
815
816 if (dirlen <= len)
817 break;
818 cp = memchr(path + len + 1, '/', dirlen - len - 1);
819 if (!cp)
820 cp = path + dirlen;
821 strbuf_addf(&pathbuf,
822 "%.*s/%s", (int)(cp - path), path,
823 GITATTRIBUTES_FILE);
824 elem = read_attr(pathbuf.buf, 0);
825 strbuf_setlen(&pathbuf, cp - path);
826 origin = strbuf_detach(&pathbuf, &len);
827 push_stack(&attr_stack, elem, origin, len);
828 debug_push(elem);
829 }
830
831 strbuf_release(&pathbuf);
832 }
833
834 /*
835 * Finally push the "info" one at the top of the stack.
836 */
837 push_stack(&attr_stack, info, NULL, 0);
838}
839
840static int path_matches(const char *pathname, int pathlen,
841 int basename_offset,
842 const struct pattern *pat,
843 const char *base, int baselen)
844{
845 const char *pattern = pat->pattern;
846 int prefix = pat->nowildcardlen;
847 int isdir = (pathlen && pathname[pathlen - 1] == '/');
848
849 if ((pat->flags & EXC_FLAG_MUSTBEDIR) && !isdir)
850 return 0;
851
852 if (pat->flags & EXC_FLAG_NODIR) {
853 return match_basename(pathname + basename_offset,
854 pathlen - basename_offset - isdir,
855 pattern, prefix,
856 pat->patternlen, pat->flags);
857 }
858 return match_pathname(pathname, pathlen - isdir,
859 base, baselen,
860 pattern, prefix, pat->patternlen, pat->flags);
861}
862
863static int macroexpand_one(int attr_nr, int rem);
864
865static int fill_one(const char *what, struct match_attr *a, int rem)
866{
867 struct attr_check_item *check = check_all_attr;
868 int i;
869
870 for (i = a->num_attr - 1; 0 < rem && 0 <= i; i--) {
871 struct git_attr *attr = a->state[i].attr;
872 const char **n = &(check[attr->attr_nr].value);
873 const char *v = a->state[i].setto;
874
875 if (*n == ATTR__UNKNOWN) {
876 debug_set(what,
877 a->is_macro ? a->u.attr->name : a->u.pat.pattern,
878 attr, v);
879 *n = v;
880 rem--;
881 rem = macroexpand_one(attr->attr_nr, rem);
882 }
883 }
884 return rem;
885}
886
887static int fill(const char *path, int pathlen, int basename_offset,
888 struct attr_stack *stk, int rem)
889{
890 int i;
891 const char *base = stk->origin ? stk->origin : "";
892
893 for (i = stk->num_matches - 1; 0 < rem && 0 <= i; i--) {
894 struct match_attr *a = stk->attrs[i];
895 if (a->is_macro)
896 continue;
897 if (path_matches(path, pathlen, basename_offset,
898 &a->u.pat, base, stk->originlen))
899 rem = fill_one("fill", a, rem);
900 }
901 return rem;
902}
903
904static int macroexpand_one(int nr, int rem)
905{
906 struct attr_stack *stk;
907 int i;
908
909 if (check_all_attr[nr].value != ATTR__TRUE ||
910 !check_all_attr[nr].attr->maybe_macro)
911 return rem;
912
913 for (stk = attr_stack; stk; stk = stk->prev) {
914 for (i = stk->num_matches - 1; 0 <= i; i--) {
915 struct match_attr *ma = stk->attrs[i];
916 if (!ma->is_macro)
917 continue;
918 if (ma->u.attr->attr_nr == nr)
919 return fill_one("expand", ma, rem);
920 }
921 }
922
923 return rem;
924}
925
926/*
927 * Collect attributes for path into the array pointed to by
928 * check_all_attr. If num is non-zero, only attributes in check[] are
929 * collected. Otherwise all attributes are collected.
930 */
931static void collect_some_attrs(const char *path, struct attr_check *check)
932{
933 struct attr_stack *stk;
934 int i, pathlen, rem, dirlen;
935 const char *cp, *last_slash = NULL;
936 int basename_offset;
937
938 for (cp = path; *cp; cp++) {
939 if (*cp == '/' && cp[1])
940 last_slash = cp;
941 }
942 pathlen = cp - path;
943 if (last_slash) {
944 basename_offset = last_slash + 1 - path;
945 dirlen = last_slash - path;
946 } else {
947 basename_offset = 0;
948 dirlen = 0;
949 }
950
951 prepare_attr_stack(path, dirlen);
952 for (i = 0; i < attr_nr; i++)
953 check_all_attr[i].value = ATTR__UNKNOWN;
954 if (check->nr && !cannot_trust_maybe_real) {
955 rem = 0;
956 for (i = 0; i < check->nr; i++) {
957 const struct git_attr *a = check->items[i].attr;
958 if (!a->maybe_real) {
959 struct attr_check_item *c;
960 c = check_all_attr + a->attr_nr;
961 c->value = ATTR__UNSET;
962 rem++;
963 }
964 }
965 if (rem == check->nr)
966 return;
967 }
968
969 rem = attr_nr;
970 for (stk = attr_stack; 0 < rem && stk; stk = stk->prev)
971 rem = fill(path, pathlen, basename_offset, stk, rem);
972}
973
974int git_check_attr(const char *path, struct attr_check *check)
975{
976 int i;
977
978 collect_some_attrs(path, check);
979
980 for (i = 0; i < check->nr; i++) {
981 const char *value = check_all_attr[check->items[i].attr->attr_nr].value;
982 if (value == ATTR__UNKNOWN)
983 value = ATTR__UNSET;
984 check->items[i].value = value;
985 }
986
987 return 0;
988}
989
990void git_all_attrs(const char *path, struct attr_check *check)
991{
992 int i;
993
994 attr_check_reset(check);
995 collect_some_attrs(path, check);
996
997 for (i = 0; i < attr_nr; i++) {
998 const char *name = check_all_attr[i].attr->name;
999 const char *value = check_all_attr[i].value;
1000 struct attr_check_item *item;
1001 if (value == ATTR__UNSET || value == ATTR__UNKNOWN)
1002 continue;
1003 item = attr_check_append(check, git_attr(name));
1004 item->value = value;
1005 }
1006}
1007
1008void git_attr_set_direction(enum git_attr_direction new, struct index_state *istate)
1009{
1010 enum git_attr_direction old = direction;
1011
1012 if (is_bare_repository() && new != GIT_ATTR_INDEX)
1013 die("BUG: non-INDEX attr direction in a bare repo");
1014
1015 direction = new;
1016 if (new != old)
1017 drop_attr_stack();
1018 use_index = istate;
1019}
1020
1021void attr_start(void)
1022{
1023#ifndef NO_PTHREADS
1024 pthread_mutex_init(&g_attr_hashmap.mutex, NULL);
1025#endif
1026}