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