git
/
attr.c
1383 строки · 34.6 Кб
1/*
2* Handle git attributes. See gitattributes(5) for a description of
3* the file syntax, and attr.h for a description of the API.
4*
5* One basic design decision here is that we are not going to support
6* an insanely large number of attributes.
7*/
8
9#define USE_THE_REPOSITORY_VARIABLE10
11#include "git-compat-util.h"12#include "config.h"13#include "environment.h"14#include "exec-cmd.h"15#include "attr.h"16#include "dir.h"17#include "gettext.h"18#include "path.h"19#include "utf8.h"20#include "quote.h"21#include "read-cache-ll.h"22#include "refs.h"23#include "revision.h"24#include "object-store-ll.h"25#include "setup.h"26#include "thread-utils.h"27#include "tree-walk.h"28#include "object-name.h"29
30char *git_attr_tree;31
32const char git_attr__true[] = "(builtin)true";33const char git_attr__false[] = "\0(builtin)false";34static const char git_attr__unknown[] = "(builtin)unknown";35#define ATTR__TRUE git_attr__true36#define ATTR__FALSE git_attr__false37#define ATTR__UNSET NULL38#define ATTR__UNKNOWN git_attr__unknown39
40struct git_attr {41unsigned int attr_nr; /* unique attribute number */42char name[FLEX_ARRAY]; /* attribute name */43};44
45const char *git_attr_name(const struct git_attr *attr)46{
47return attr->name;48}
49
50struct attr_hashmap {51struct hashmap map;52pthread_mutex_t mutex;53};54
55static inline void hashmap_lock(struct attr_hashmap *map)56{
57pthread_mutex_lock(&map->mutex);58}
59
60static inline void hashmap_unlock(struct attr_hashmap *map)61{
62pthread_mutex_unlock(&map->mutex);63}
64
65/* The container for objects stored in "struct attr_hashmap" */
66struct attr_hash_entry {67struct hashmap_entry ent;68const char *key; /* the key; memory should be owned by value */69size_t keylen; /* length of the key */70void *value; /* the stored value */71};72
73/* attr_hashmap comparison function */
74static int attr_hash_entry_cmp(const void *cmp_data UNUSED,75const struct hashmap_entry *eptr,76const struct hashmap_entry *entry_or_key,77const void *keydata UNUSED)78{
79const struct attr_hash_entry *a, *b;80
81a = container_of(eptr, const struct attr_hash_entry, ent);82b = container_of(entry_or_key, const struct attr_hash_entry, ent);83return (a->keylen != b->keylen) || strncmp(a->key, b->key, a->keylen);84}
85
86/*
87* The global dictionary of all interned attributes. This
88* is a singleton object which is shared between threads.
89* Access to this dictionary must be surrounded with a mutex.
90*/
91static struct attr_hashmap g_attr_hashmap = {92.map = HASHMAP_INIT(attr_hash_entry_cmp, NULL),93};94
95/*
96* Retrieve the 'value' stored in a hashmap given the provided 'key'.
97* If there is no matching entry, return NULL.
98*/
99static void *attr_hashmap_get(struct attr_hashmap *map,100const char *key, size_t keylen)101{
102struct attr_hash_entry k;103struct attr_hash_entry *e;104
105hashmap_entry_init(&k.ent, memhash(key, keylen));106k.key = key;107k.keylen = keylen;108e = hashmap_get_entry(&map->map, &k, ent, NULL);109
110return e ? e->value : NULL;111}
112
113/* Add 'value' to a hashmap based on the provided 'key'. */
114static void attr_hashmap_add(struct attr_hashmap *map,115const char *key, size_t keylen,116void *value)117{
118struct attr_hash_entry *e;119
120e = xmalloc(sizeof(struct attr_hash_entry));121hashmap_entry_init(&e->ent, memhash(key, keylen));122e->key = key;123e->keylen = keylen;124e->value = value;125
126hashmap_add(&map->map, &e->ent);127}
128
129struct all_attrs_item {130const struct git_attr *attr;131const char *value;132/*133* If 'macro' is non-NULL, indicates that 'attr' is a macro based on
134* the current attribute stack and contains a pointer to the match_attr
135* definition of the macro
136*/
137const struct match_attr *macro;138};139
140/*
141* Reallocate and reinitialize the array of all attributes (which is used in
142* the attribute collection process) in 'check' based on the global dictionary
143* of attributes.
144*/
145static void all_attrs_init(struct attr_hashmap *map, struct attr_check *check)146{
147int i;148unsigned int size;149
150hashmap_lock(map);151
152size = hashmap_get_size(&map->map);153if (size < check->all_attrs_nr)154BUG("interned attributes shouldn't be deleted");155
156/*157* If the number of attributes in the global dictionary has increased
158* (or this attr_check instance doesn't have an initialized all_attrs
159* field), reallocate the provided attr_check instance's all_attrs
160* field and fill each entry with its corresponding git_attr.
161*/
162if (size != check->all_attrs_nr) {163struct attr_hash_entry *e;164struct hashmap_iter iter;165
166REALLOC_ARRAY(check->all_attrs, size);167check->all_attrs_nr = size;168
169hashmap_for_each_entry(&map->map, &iter, e,170ent /* member name */) {171const struct git_attr *a = e->value;172check->all_attrs[a->attr_nr].attr = a;173}174}175
176hashmap_unlock(map);177
178/*179* Re-initialize every entry in check->all_attrs.
180* This re-initialization can live outside of the locked region since
181* the attribute dictionary is no longer being accessed.
182*/
183for (i = 0; i < check->all_attrs_nr; i++) {184check->all_attrs[i].value = ATTR__UNKNOWN;185check->all_attrs[i].macro = NULL;186}187}
188
189/*
190* Atribute name cannot begin with "builtin_" which
191* is a reserved namespace for built in attributes values.
192*/
193static int attr_name_reserved(const char *name)194{
195return starts_with(name, "builtin_");196}
197
198static int attr_name_valid(const char *name, size_t namelen)199{
200/*201* Attribute name cannot begin with '-' and must consist of
202* characters from [-A-Za-z0-9_.].
203*/
204if (namelen <= 0 || *name == '-')205return 0;206while (namelen--) {207char ch = *name++;208if (! (ch == '-' || ch == '.' || ch == '_' ||209('0' <= ch && ch <= '9') ||210('a' <= ch && ch <= 'z') ||211('A' <= ch && ch <= 'Z')) )212return 0;213}214return 1;215}
216
217static void report_invalid_attr(const char *name, size_t len,218const char *src, int lineno)219{
220struct strbuf err = STRBUF_INIT;221strbuf_addf(&err, _("%.*s is not a valid attribute name"),222(int) len, name);223fprintf(stderr, "%s: %s:%d\n", err.buf, src, lineno);224strbuf_release(&err);225}
226
227/*
228* Given a 'name', lookup and return the corresponding attribute in the global
229* dictionary. If no entry is found, create a new attribute and store it in
230* the dictionary.
231*/
232static const struct git_attr *git_attr_internal(const char *name, size_t namelen)233{
234struct git_attr *a;235
236if (!attr_name_valid(name, namelen))237return NULL;238
239hashmap_lock(&g_attr_hashmap);240
241a = attr_hashmap_get(&g_attr_hashmap, name, namelen);242
243if (!a) {244FLEX_ALLOC_MEM(a, name, name, namelen);245a->attr_nr = hashmap_get_size(&g_attr_hashmap.map);246
247attr_hashmap_add(&g_attr_hashmap, a->name, namelen, a);248if (a->attr_nr != hashmap_get_size(&g_attr_hashmap.map) - 1)249die(_("unable to add additional attribute"));250}251
252hashmap_unlock(&g_attr_hashmap);253
254return a;255}
256
257const struct git_attr *git_attr(const char *name)258{
259return git_attr_internal(name, strlen(name));260}
261
262/* What does a matched pattern decide? */
263struct attr_state {264const struct git_attr *attr;265const char *setto;266};267
268struct pattern {269const char *pattern;270int patternlen;271int nowildcardlen;272unsigned flags; /* PATTERN_FLAG_* */273};274
275/*
276* One rule, as from a .gitattributes file.
277*
278* If is_macro is true, then u.attr is a pointer to the git_attr being
279* defined.
280*
281* If is_macro is false, then u.pat is the filename pattern to which the
282* rule applies.
283*
284* In either case, num_attr is the number of attributes affected by
285* this rule, and state is an array listing them. The attributes are
286* listed as they appear in the file (macros unexpanded).
287*/
288struct match_attr {289union {290struct pattern pat;291const struct git_attr *attr;292} u;293char is_macro;294size_t num_attr;295struct attr_state state[FLEX_ARRAY];296};297
298static const char blank[] = " \t\r\n";299
300/* Flags usable in read_attr() and parse_attr_line() family of functions. */
301#define READ_ATTR_MACRO_OK (1<<0)302#define READ_ATTR_NOFOLLOW (1<<1)303
304/*
305* Parse a whitespace-delimited attribute state (i.e., "attr",
306* "-attr", "!attr", or "attr=value") from the string starting at src.
307* If e is not NULL, write the results to *e. Return a pointer to the
308* remainder of the string (with leading whitespace removed), or NULL
309* if there was an error.
310*/
311static const char *parse_attr(const char *src, int lineno, const char *cp,312struct attr_state *e)313{
314const char *ep, *equals;315size_t len;316
317ep = cp + strcspn(cp, blank);318equals = strchr(cp, '=');319if (equals && ep < equals)320equals = NULL;321if (equals)322len = equals - cp;323else324len = ep - cp;325if (!e) {326if (*cp == '-' || *cp == '!') {327cp++;328len--;329}330if (!attr_name_valid(cp, len) || attr_name_reserved(cp)) {331report_invalid_attr(cp, len, src, lineno);332return NULL;333}334} else {335/*336* As this function is always called twice, once with
337* e == NULL in the first pass and then e != NULL in
338* the second pass, no need for attr_name_valid()
339* check here.
340*/
341if (*cp == '-' || *cp == '!') {342e->setto = (*cp == '-') ? ATTR__FALSE : ATTR__UNSET;343cp++;344len--;345}346else if (!equals)347e->setto = ATTR__TRUE;348else {349e->setto = xmemdupz(equals + 1, ep - equals - 1);350}351e->attr = git_attr_internal(cp, len);352}353return ep + strspn(ep, blank);354}
355
356static struct match_attr *parse_attr_line(const char *line, const char *src,357int lineno, unsigned flags)358{
359size_t namelen, num_attr, i;360const char *cp, *name, *states;361struct match_attr *res = NULL;362int is_macro;363struct strbuf pattern = STRBUF_INIT;364
365cp = line + strspn(line, blank);366if (!*cp || *cp == '#')367return NULL;368name = cp;369
370if (strlen(line) >= ATTR_MAX_LINE_LENGTH) {371warning(_("ignoring overly long attributes line %d"), lineno);372return NULL;373}374
375if (*cp == '"' && !unquote_c_style(&pattern, name, &states)) {376name = pattern.buf;377namelen = pattern.len;378} else {379namelen = strcspn(name, blank);380states = name + namelen;381}382
383if (strlen(ATTRIBUTE_MACRO_PREFIX) < namelen &&384starts_with(name, ATTRIBUTE_MACRO_PREFIX)) {385if (!(flags & READ_ATTR_MACRO_OK)) {386fprintf_ln(stderr, _("%s not allowed: %s:%d"),387name, src, lineno);388goto fail_return;389}390is_macro = 1;391name += strlen(ATTRIBUTE_MACRO_PREFIX);392name += strspn(name, blank);393namelen = strcspn(name, blank);394if (!attr_name_valid(name, namelen) || attr_name_reserved(name)) {395report_invalid_attr(name, namelen, src, lineno);396goto fail_return;397}398}399else400is_macro = 0;401
402states += strspn(states, blank);403
404/* First pass to count the attr_states */405for (cp = states, num_attr = 0; *cp; num_attr++) {406cp = parse_attr(src, lineno, cp, NULL);407if (!cp)408goto fail_return;409}410
411res = xcalloc(1, st_add3(sizeof(*res),412st_mult(sizeof(struct attr_state), num_attr),413is_macro ? 0 : namelen + 1));414if (is_macro) {415res->u.attr = git_attr_internal(name, namelen);416} else {417char *p = (char *)&(res->state[num_attr]);418memcpy(p, name, namelen);419res->u.pat.pattern = p;420parse_path_pattern(&res->u.pat.pattern,421&res->u.pat.patternlen,422&res->u.pat.flags,423&res->u.pat.nowildcardlen);424if (res->u.pat.flags & PATTERN_FLAG_NEGATIVE) {425warning(_("Negative patterns are ignored in git attributes\n"426"Use '\\!' for literal leading exclamation."));427goto fail_return;428}429}430res->is_macro = is_macro;431res->num_attr = num_attr;432
433/* Second pass to fill the attr_states */434for (cp = states, i = 0; *cp; i++) {435cp = parse_attr(src, lineno, cp, &(res->state[i]));436}437
438strbuf_release(&pattern);439return res;440
441fail_return:442strbuf_release(&pattern);443free(res);444return NULL;445}
446
447/*
448* Like info/exclude and .gitignore, the attribute information can
449* come from many places.
450*
451* (1) .gitattributes file of the same directory;
452* (2) .gitattributes file of the parent directory if (1) does not have
453* any match; this goes recursively upwards, just like .gitignore.
454* (3) $GIT_DIR/info/attributes, which overrides both of the above.
455*
456* In the same file, later entries override the earlier match, so in the
457* global list, we would have entries from info/attributes the earliest
458* (reading the file from top to bottom), .gitattributes of the root
459* directory (again, reading the file from top to bottom) down to the
460* current directory, and then scan the list backwards to find the first match.
461* This is exactly the same as what is_excluded() does in dir.c to deal with
462* .gitignore file and info/excludes file as a fallback.
463*/
464
465struct attr_stack {466struct attr_stack *prev;467char *origin;468size_t originlen;469unsigned num_matches;470unsigned alloc;471struct match_attr **attrs;472};473
474static void attr_stack_free(struct attr_stack *e)475{
476unsigned i;477free(e->origin);478for (i = 0; i < e->num_matches; i++) {479struct match_attr *a = e->attrs[i];480size_t j;481
482for (j = 0; j < a->num_attr; j++) {483const char *setto = a->state[j].setto;484if (setto == ATTR__TRUE ||485setto == ATTR__FALSE ||486setto == ATTR__UNSET ||487setto == ATTR__UNKNOWN)488;489else490free((char *) setto);491}492free(a);493}494free(e->attrs);495free(e);496}
497
498static void drop_attr_stack(struct attr_stack **stack)499{
500while (*stack) {501struct attr_stack *elem = *stack;502*stack = elem->prev;503attr_stack_free(elem);504}505}
506
507/* List of all attr_check structs; access should be surrounded by mutex */
508static struct check_vector {509size_t nr;510size_t alloc;511struct attr_check **checks;512pthread_mutex_t mutex;513} check_vector;514
515static inline void vector_lock(void)516{
517pthread_mutex_lock(&check_vector.mutex);518}
519
520static inline void vector_unlock(void)521{
522pthread_mutex_unlock(&check_vector.mutex);523}
524
525static void check_vector_add(struct attr_check *c)526{
527vector_lock();528
529ALLOC_GROW(check_vector.checks,530check_vector.nr + 1,531check_vector.alloc);532check_vector.checks[check_vector.nr++] = c;533
534vector_unlock();535}
536
537static void check_vector_remove(struct attr_check *check)538{
539int i;540
541vector_lock();542
543/* Find entry */544for (i = 0; i < check_vector.nr; i++)545if (check_vector.checks[i] == check)546break;547
548if (i >= check_vector.nr)549BUG("no entry found");550
551/* shift entries over */552for (; i < check_vector.nr - 1; i++)553check_vector.checks[i] = check_vector.checks[i + 1];554
555check_vector.nr--;556
557vector_unlock();558}
559
560/* Iterate through all attr_check instances and drop their stacks */
561static void drop_all_attr_stacks(void)562{
563int i;564
565vector_lock();566
567for (i = 0; i < check_vector.nr; i++) {568drop_attr_stack(&check_vector.checks[i]->stack);569}570
571vector_unlock();572}
573
574struct attr_check *attr_check_alloc(void)575{
576struct attr_check *c = xcalloc(1, sizeof(struct attr_check));577
578/* save pointer to the check struct */579check_vector_add(c);580
581return c;582}
583
584struct attr_check *attr_check_initl(const char *one, ...)585{
586struct attr_check *check;587int cnt;588va_list params;589const char *param;590
591va_start(params, one);592for (cnt = 1; (param = va_arg(params, const char *)) != NULL; cnt++)593;594va_end(params);595
596check = attr_check_alloc();597check->nr = cnt;598check->alloc = cnt;599CALLOC_ARRAY(check->items, cnt);600
601check->items[0].attr = git_attr(one);602va_start(params, one);603for (cnt = 1; cnt < check->nr; cnt++) {604const struct git_attr *attr;605param = va_arg(params, const char *);606if (!param)607BUG("counted %d != ended at %d",608check->nr, cnt);609attr = git_attr(param);610if (!attr)611BUG("%s: not a valid attribute name", param);612check->items[cnt].attr = attr;613}614va_end(params);615return check;616}
617
618struct attr_check *attr_check_dup(const struct attr_check *check)619{
620struct attr_check *ret;621
622if (!check)623return NULL;624
625ret = attr_check_alloc();626
627ret->nr = check->nr;628ret->alloc = check->alloc;629DUP_ARRAY(ret->items, check->items, ret->nr);630
631return ret;632}
633
634struct attr_check_item *attr_check_append(struct attr_check *check,635const struct git_attr *attr)636{
637struct attr_check_item *item;638
639ALLOC_GROW(check->items, check->nr + 1, check->alloc);640item = &check->items[check->nr++];641item->attr = attr;642return item;643}
644
645void attr_check_reset(struct attr_check *check)646{
647check->nr = 0;648}
649
650void attr_check_clear(struct attr_check *check)651{
652FREE_AND_NULL(check->items);653check->alloc = 0;654check->nr = 0;655
656FREE_AND_NULL(check->all_attrs);657check->all_attrs_nr = 0;658
659drop_attr_stack(&check->stack);660}
661
662void attr_check_free(struct attr_check *check)663{
664if (check) {665/* Remove check from the check vector */666check_vector_remove(check);667
668attr_check_clear(check);669free(check);670}671}
672
673static const char *builtin_attr[] = {674"[attr]binary -diff -merge -text",675NULL,676};677
678static void handle_attr_line(struct attr_stack *res,679const char *line,680const char *src,681int lineno,682unsigned flags)683{
684struct match_attr *a;685
686a = parse_attr_line(line, src, lineno, flags);687if (!a)688return;689ALLOC_GROW_BY(res->attrs, res->num_matches, 1, res->alloc);690res->attrs[res->num_matches - 1] = a;691}
692
693static struct attr_stack *read_attr_from_array(const char **list)694{
695struct attr_stack *res;696const char *line;697int lineno = 0;698
699CALLOC_ARRAY(res, 1);700while ((line = *(list++)) != NULL)701handle_attr_line(res, line, "[builtin]", ++lineno,702READ_ATTR_MACRO_OK);703return res;704}
705
706/*
707* Callers into the attribute system assume there is a single, system-wide
708* global state where attributes are read from and when the state is flipped by
709* calling git_attr_set_direction(), the stack frames that have been
710* constructed need to be discarded so that subsequent calls into the
711* attribute system will lazily read from the right place. Since changing
712* direction causes a global paradigm shift, it should not ever be called while
713* another thread could potentially be calling into the attribute system.
714*/
715static enum git_attr_direction direction;716
717void git_attr_set_direction(enum git_attr_direction new_direction)718{
719if (is_bare_repository() && new_direction != GIT_ATTR_INDEX)720BUG("non-INDEX attr direction in a bare repo");721
722if (new_direction != direction)723drop_all_attr_stacks();724
725direction = new_direction;726}
727
728static struct attr_stack *read_attr_from_file(const char *path, unsigned flags)729{
730struct strbuf buf = STRBUF_INIT;731int fd;732FILE *fp;733struct attr_stack *res;734int lineno = 0;735struct stat st;736
737if (flags & READ_ATTR_NOFOLLOW)738fd = open_nofollow(path, O_RDONLY);739else740fd = open(path, O_RDONLY);741
742if (fd < 0) {743warn_on_fopen_errors(path);744return NULL;745}746fp = xfdopen(fd, "r");747if (fstat(fd, &st)) {748warning_errno(_("cannot fstat gitattributes file '%s'"), path);749fclose(fp);750return NULL;751}752if (st.st_size >= ATTR_MAX_FILE_SIZE) {753warning(_("ignoring overly large gitattributes file '%s'"), path);754fclose(fp);755return NULL;756}757
758CALLOC_ARRAY(res, 1);759while (strbuf_getline(&buf, fp) != EOF) {760if (!lineno && starts_with(buf.buf, utf8_bom))761strbuf_remove(&buf, 0, strlen(utf8_bom));762handle_attr_line(res, buf.buf, path, ++lineno, flags);763}764
765fclose(fp);766strbuf_release(&buf);767return res;768}
769
770static struct attr_stack *read_attr_from_buf(char *buf, size_t length,771const char *path, unsigned flags)772{
773struct attr_stack *res;774char *sp;775int lineno = 0;776
777if (!buf)778return NULL;779if (length >= ATTR_MAX_FILE_SIZE) {780warning(_("ignoring overly large gitattributes blob '%s'"), path);781free(buf);782return NULL;783}784
785CALLOC_ARRAY(res, 1);786for (sp = buf; *sp;) {787char *ep;788int more;789
790ep = strchrnul(sp, '\n');791more = (*ep == '\n');792*ep = '\0';793handle_attr_line(res, sp, path, ++lineno, flags);794sp = ep + more;795}796free(buf);797
798return res;799}
800
801static struct attr_stack *read_attr_from_blob(struct index_state *istate,802const struct object_id *tree_oid,803const char *path, unsigned flags)804{
805struct object_id oid;806unsigned long sz;807enum object_type type;808void *buf;809unsigned short mode;810
811if (!tree_oid)812return NULL;813
814if (get_tree_entry(istate->repo, tree_oid, path, &oid, &mode))815return NULL;816
817buf = repo_read_object_file(istate->repo, &oid, &type, &sz);818if (!buf || type != OBJ_BLOB) {819free(buf);820return NULL;821}822
823return read_attr_from_buf(buf, sz, path, flags);824}
825
826static struct attr_stack *read_attr_from_index(struct index_state *istate,827const char *path, unsigned flags)828{
829struct attr_stack *stack = NULL;830char *buf;831unsigned long size;832int sparse_dir_pos = -1;833
834if (!istate)835return NULL;836
837/*838* When handling sparse-checkouts, .gitattributes files
839* may reside within a sparse directory. We distinguish
840* whether a path exists directly in the index or not by
841* evaluating if 'pos' is negative.
842* If 'pos' is negative, the path is not directly present
843* in the index and is likely within a sparse directory.
844* For paths not in the index, The absolute value of 'pos'
845* minus 1 gives us the position where the path would be
846* inserted in lexicographic order within the index.
847* We then subtract another 1 from this value
848* (sparse_dir_pos = -pos - 2) to find the position of the
849* last index entry which is lexicographically smaller than
850* the path. This would be the sparse directory containing
851* the path. By identifying the sparse directory containing
852* the path, we can correctly read the attributes specified
853* in the .gitattributes file from the tree object of the
854* sparse directory.
855*/
856if (!path_in_cone_mode_sparse_checkout(path, istate)) {857int pos = index_name_pos_sparse(istate, path, strlen(path));858
859if (pos < 0)860sparse_dir_pos = -pos - 2;861}862
863if (sparse_dir_pos >= 0 &&864S_ISSPARSEDIR(istate->cache[sparse_dir_pos]->ce_mode) &&865!strncmp(istate->cache[sparse_dir_pos]->name, path, ce_namelen(istate->cache[sparse_dir_pos]))) {866const char *relative_path = path + ce_namelen(istate->cache[sparse_dir_pos]);867stack = read_attr_from_blob(istate, &istate->cache[sparse_dir_pos]->oid, relative_path, flags);868} else {869buf = read_blob_data_from_index(istate, path, &size);870if (buf)871stack = read_attr_from_buf(buf, size, path, flags);872}873return stack;874}
875
876static struct attr_stack *read_attr(struct index_state *istate,877const struct object_id *tree_oid,878const char *path, unsigned flags)879{
880struct attr_stack *res = NULL;881
882if (direction == GIT_ATTR_INDEX) {883res = read_attr_from_index(istate, path, flags);884} else if (tree_oid) {885res = read_attr_from_blob(istate, tree_oid, path, flags);886} else if (!is_bare_repository()) {887if (direction == GIT_ATTR_CHECKOUT) {888res = read_attr_from_index(istate, path, flags);889if (!res)890res = read_attr_from_file(path, flags);891} else if (direction == GIT_ATTR_CHECKIN) {892res = read_attr_from_file(path, flags);893if (!res)894/*895* There is no checked out .gitattributes file
896* there, but we might have it in the index.
897* We allow operation in a sparsely checked out
898* work tree, so read from it.
899*/
900res = read_attr_from_index(istate, path, flags);901}902}903
904if (!res)905CALLOC_ARRAY(res, 1);906return res;907}
908
909const char *git_attr_system_file(void)910{
911static const char *system_wide;912if (!system_wide)913system_wide = system_path(ETC_GITATTRIBUTES);914return system_wide;915}
916
917const char *git_attr_global_file(void)918{
919if (!git_attributes_file)920git_attributes_file = xdg_config_home("attributes");921
922return git_attributes_file;923}
924
925int git_attr_system_is_enabled(void)926{
927return !git_env_bool("GIT_ATTR_NOSYSTEM", 0);928}
929
930static GIT_PATH_FUNC(git_path_info_attributes, INFOATTRIBUTES_FILE)931
932static void push_stack(struct attr_stack **attr_stack_p,933struct attr_stack *elem, char *origin, size_t originlen)934{
935if (elem) {936elem->origin = origin;937if (origin)938elem->originlen = originlen;939elem->prev = *attr_stack_p;940*attr_stack_p = elem;941}942}
943
944static void bootstrap_attr_stack(struct index_state *istate,945const struct object_id *tree_oid,946struct attr_stack **stack)947{
948struct attr_stack *e;949unsigned flags = READ_ATTR_MACRO_OK;950
951if (*stack)952return;953
954/* builtin frame */955e = read_attr_from_array(builtin_attr);956push_stack(stack, e, NULL, 0);957
958/* system-wide frame */959if (git_attr_system_is_enabled()) {960e = read_attr_from_file(git_attr_system_file(), flags);961push_stack(stack, e, NULL, 0);962}963
964/* home directory */965if (git_attr_global_file()) {966e = read_attr_from_file(git_attr_global_file(), flags);967push_stack(stack, e, NULL, 0);968}969
970/* root directory */971e = read_attr(istate, tree_oid, GITATTRIBUTES_FILE, flags | READ_ATTR_NOFOLLOW);972push_stack(stack, e, xstrdup(""), 0);973
974/* info frame */975if (startup_info->have_repository)976e = read_attr_from_file(git_path_info_attributes(), flags);977else978e = NULL;979if (!e)980CALLOC_ARRAY(e, 1);981push_stack(stack, e, NULL, 0);982}
983
984static void prepare_attr_stack(struct index_state *istate,985const struct object_id *tree_oid,986const char *path, int dirlen,987struct attr_stack **stack)988{
989struct attr_stack *info;990struct strbuf pathbuf = STRBUF_INIT;991
992/*993* At the bottom of the attribute stack is the built-in
994* set of attribute definitions, followed by the contents
995* of $(prefix)/etc/gitattributes and a file specified by
996* core.attributesfile. Then, contents from
997* .gitattributes files from directories closer to the
998* root to the ones in deeper directories are pushed
999* to the stack. Finally, at the very top of the stack
1000* we always keep the contents of $GIT_DIR/info/attributes.
1001*
1002* When checking, we use entries from near the top of the
1003* stack, preferring $GIT_DIR/info/attributes, then
1004* .gitattributes in deeper directories to shallower ones,
1005* and finally use the built-in set as the default.
1006*/
1007bootstrap_attr_stack(istate, tree_oid, stack);1008
1009/*1010* Pop the "info" one that is always at the top of the stack.
1011*/
1012info = *stack;1013*stack = info->prev;1014
1015/*1016* Pop the ones from directories that are not the prefix of
1017* the path we are checking. Break out of the loop when we see
1018* the root one (whose origin is an empty string "") or the builtin
1019* one (whose origin is NULL) without popping it.
1020*/
1021while ((*stack)->origin) {1022int namelen = (*stack)->originlen;1023struct attr_stack *elem;1024
1025elem = *stack;1026if (namelen <= dirlen &&1027!strncmp(elem->origin, path, namelen) &&1028(!namelen || path[namelen] == '/'))1029break;1030
1031*stack = elem->prev;1032attr_stack_free(elem);1033}1034
1035/*1036* bootstrap_attr_stack() should have added, and the
1037* above loop should have stopped before popping, the
1038* root element whose attr_stack->origin is set to an
1039* empty string.
1040*/
1041assert((*stack)->origin);1042
1043strbuf_addstr(&pathbuf, (*stack)->origin);1044/* Build up to the directory 'path' is in */1045while (pathbuf.len < dirlen) {1046size_t len = pathbuf.len;1047struct attr_stack *next;1048char *origin;1049
1050/* Skip path-separator */1051if (len < dirlen && is_dir_sep(path[len]))1052len++;1053/* Find the end of the next component */1054while (len < dirlen && !is_dir_sep(path[len]))1055len++;1056
1057if (pathbuf.len > 0)1058strbuf_addch(&pathbuf, '/');1059strbuf_add(&pathbuf, path + pathbuf.len, (len - pathbuf.len));1060strbuf_addf(&pathbuf, "/%s", GITATTRIBUTES_FILE);1061
1062next = read_attr(istate, tree_oid, pathbuf.buf, READ_ATTR_NOFOLLOW);1063
1064/* reset the pathbuf to not include "/.gitattributes" */1065strbuf_setlen(&pathbuf, len);1066
1067origin = xstrdup(pathbuf.buf);1068push_stack(stack, next, origin, len);1069}1070
1071/*1072* Finally push the "info" one at the top of the stack.
1073*/
1074push_stack(stack, info, NULL, 0);1075
1076strbuf_release(&pathbuf);1077}
1078
1079static int path_matches(const char *pathname, int pathlen,1080int basename_offset,1081const struct pattern *pat,1082const char *base, int baselen)1083{
1084const char *pattern = pat->pattern;1085int prefix = pat->nowildcardlen;1086int isdir = (pathlen && pathname[pathlen - 1] == '/');1087
1088if ((pat->flags & PATTERN_FLAG_MUSTBEDIR) && !isdir)1089return 0;1090
1091if (pat->flags & PATTERN_FLAG_NODIR) {1092return match_basename(pathname + basename_offset,1093pathlen - basename_offset - isdir,1094pattern, prefix,1095pat->patternlen, pat->flags);1096}1097return match_pathname(pathname, pathlen - isdir,1098base, baselen,1099pattern, prefix, pat->patternlen);1100}
1101
1102static int macroexpand_one(struct all_attrs_item *all_attrs, int nr, int rem);1103
1104static int fill_one(struct all_attrs_item *all_attrs,1105const struct match_attr *a, int rem)1106{
1107size_t i;1108
1109for (i = a->num_attr; rem > 0 && i > 0; i--) {1110const struct git_attr *attr = a->state[i - 1].attr;1111const char **n = &(all_attrs[attr->attr_nr].value);1112const char *v = a->state[i - 1].setto;1113
1114if (*n == ATTR__UNKNOWN) {1115*n = v;1116rem--;1117rem = macroexpand_one(all_attrs, attr->attr_nr, rem);1118}1119}1120return rem;1121}
1122
1123static int fill(const char *path, int pathlen, int basename_offset,1124const struct attr_stack *stack,1125struct all_attrs_item *all_attrs, int rem)1126{
1127for (; rem > 0 && stack; stack = stack->prev) {1128unsigned i;1129const char *base = stack->origin ? stack->origin : "";1130
1131for (i = stack->num_matches; 0 < rem && 0 < i; i--) {1132const struct match_attr *a = stack->attrs[i - 1];1133if (a->is_macro)1134continue;1135if (path_matches(path, pathlen, basename_offset,1136&a->u.pat, base, stack->originlen))1137rem = fill_one(all_attrs, a, rem);1138}1139}1140
1141return rem;1142}
1143
1144static int macroexpand_one(struct all_attrs_item *all_attrs, int nr, int rem)1145{
1146const struct all_attrs_item *item = &all_attrs[nr];1147
1148if (item->macro && item->value == ATTR__TRUE)1149return fill_one(all_attrs, item->macro, rem);1150else1151return rem;1152}
1153
1154/*
1155* Marks the attributes which are macros based on the attribute stack.
1156* This prevents having to search through the attribute stack each time
1157* a macro needs to be expanded during the fill stage.
1158*/
1159static void determine_macros(struct all_attrs_item *all_attrs,1160const struct attr_stack *stack)1161{
1162for (; stack; stack = stack->prev) {1163unsigned i;1164for (i = stack->num_matches; i > 0; i--) {1165const struct match_attr *ma = stack->attrs[i - 1];1166if (ma->is_macro) {1167unsigned int n = ma->u.attr->attr_nr;1168if (!all_attrs[n].macro) {1169all_attrs[n].macro = ma;1170}1171}1172}1173}1174}
1175
1176/*
1177* Collect attributes for path into the array pointed to by check->all_attrs.
1178* If check->check_nr is non-zero, only attributes in check[] are collected.
1179* Otherwise all attributes are collected.
1180*/
1181static void collect_some_attrs(struct index_state *istate,1182const struct object_id *tree_oid,1183const char *path, struct attr_check *check)1184{
1185int pathlen, rem, dirlen;1186const char *cp, *last_slash = NULL;1187int basename_offset;1188
1189for (cp = path; *cp; cp++) {1190if (*cp == '/' && cp[1])1191last_slash = cp;1192}1193pathlen = cp - path;1194if (last_slash) {1195basename_offset = last_slash + 1 - path;1196dirlen = last_slash - path;1197} else {1198basename_offset = 0;1199dirlen = 0;1200}1201
1202prepare_attr_stack(istate, tree_oid, path, dirlen, &check->stack);1203all_attrs_init(&g_attr_hashmap, check);1204determine_macros(check->all_attrs, check->stack);1205
1206rem = check->all_attrs_nr;1207fill(path, pathlen, basename_offset, check->stack, check->all_attrs, rem);1208}
1209
1210static const char *default_attr_source_tree_object_name;1211
1212void set_git_attr_source(const char *tree_object_name)1213{
1214default_attr_source_tree_object_name = xstrdup(tree_object_name);1215}
1216
1217static int compute_default_attr_source(struct object_id *attr_source)1218{
1219int ignore_bad_attr_tree = 0;1220
1221if (!default_attr_source_tree_object_name)1222default_attr_source_tree_object_name = getenv(GIT_ATTR_SOURCE_ENVIRONMENT);1223
1224if (!default_attr_source_tree_object_name && git_attr_tree) {1225default_attr_source_tree_object_name = git_attr_tree;1226ignore_bad_attr_tree = 1;1227}1228
1229if (!default_attr_source_tree_object_name)1230return 0;1231
1232if (!startup_info->have_repository) {1233if (!ignore_bad_attr_tree)1234die(_("cannot use --attr-source or GIT_ATTR_SOURCE without repo"));1235return 0;1236}1237
1238if (repo_get_oid_treeish(the_repository,1239default_attr_source_tree_object_name,1240attr_source)) {1241if (!ignore_bad_attr_tree)1242die(_("bad --attr-source or GIT_ATTR_SOURCE"));1243return 0;1244}1245
1246return 1;1247}
1248
1249static struct object_id *default_attr_source(void)1250{
1251static struct object_id attr_source;1252static int has_attr_source = -1;1253
1254if (has_attr_source < 0)1255has_attr_source = compute_default_attr_source(&attr_source);1256if (!has_attr_source)1257return NULL;1258return &attr_source;1259}
1260
1261static const char *interned_mode_string(unsigned int mode)1262{
1263static struct {1264unsigned int val;1265char str[7];1266} mode_string[] = {1267{ .val = 0040000 },1268{ .val = 0100644 },1269{ .val = 0100755 },1270{ .val = 0120000 },1271{ .val = 0160000 },1272};1273int i;1274
1275for (i = 0; i < ARRAY_SIZE(mode_string); i++) {1276if (mode_string[i].val != mode)1277continue;1278if (!*mode_string[i].str)1279snprintf(mode_string[i].str, sizeof(mode_string[i].str),1280"%06o", mode);1281return mode_string[i].str;1282}1283BUG("Unsupported mode 0%o", mode);1284}
1285
1286static const char *builtin_object_mode_attr(struct index_state *istate, const char *path)1287{
1288unsigned int mode;1289
1290if (direction == GIT_ATTR_CHECKIN) {1291struct object_id oid;1292struct stat st;1293if (lstat(path, &st))1294die_errno(_("unable to stat '%s'"), path);1295mode = canon_mode(st.st_mode);1296if (S_ISDIR(mode)) {1297/*1298*`path` is either a directory or it is a submodule,
1299* in which case it is already indexed as submodule
1300* or it does not exist in the index yet and we need to
1301* check if we can resolve to a ref.
1302*/
1303int pos = index_name_pos(istate, path, strlen(path));1304if (pos >= 0) {1305if (S_ISGITLINK(istate->cache[pos]->ce_mode))1306mode = istate->cache[pos]->ce_mode;1307} else if (repo_resolve_gitlink_ref(the_repository, path,1308"HEAD", &oid) == 0) {1309mode = S_IFGITLINK;1310}1311}1312} else {1313/*1314* For GIT_ATTR_CHECKOUT and GIT_ATTR_INDEX we only check
1315* for mode in the index.
1316*/
1317int pos = index_name_pos(istate, path, strlen(path));1318if (pos >= 0)1319mode = istate->cache[pos]->ce_mode;1320else1321return ATTR__UNSET;1322}1323
1324return interned_mode_string(mode);1325}
1326
1327
1328static const char *compute_builtin_attr(struct index_state *istate,1329const char *path,1330const struct git_attr *attr) {1331static const struct git_attr *object_mode_attr;1332
1333if (!object_mode_attr)1334object_mode_attr = git_attr("builtin_objectmode");1335
1336if (attr == object_mode_attr)1337return builtin_object_mode_attr(istate, path);1338return ATTR__UNSET;1339}
1340
1341void git_check_attr(struct index_state *istate,1342const char *path,1343struct attr_check *check)1344{
1345int i;1346const struct object_id *tree_oid = default_attr_source();1347
1348collect_some_attrs(istate, tree_oid, path, check);1349
1350for (i = 0; i < check->nr; i++) {1351unsigned int n = check->items[i].attr->attr_nr;1352const char *value = check->all_attrs[n].value;1353if (value == ATTR__UNKNOWN)1354value = compute_builtin_attr(istate, path, check->all_attrs[n].attr);1355check->items[i].value = value;1356}1357}
1358
1359void git_all_attrs(struct index_state *istate,1360const char *path, struct attr_check *check)1361{
1362int i;1363const struct object_id *tree_oid = default_attr_source();1364
1365attr_check_reset(check);1366collect_some_attrs(istate, tree_oid, path, check);1367
1368for (i = 0; i < check->all_attrs_nr; i++) {1369const char *name = check->all_attrs[i].attr->name;1370const char *value = check->all_attrs[i].value;1371struct attr_check_item *item;1372if (value == ATTR__UNSET || value == ATTR__UNKNOWN)1373continue;1374item = attr_check_append(check, git_attr(name));1375item->value = value;1376}1377}
1378
1379void attr_start(void)1380{
1381pthread_mutex_init(&g_attr_hashmap.mutex, NULL);1382pthread_mutex_init(&check_vector.mutex, NULL);1383}
1384