From: Jeff King Date: Thu, 25 Oct 2012 10:42:36 +0000 (-0400) Subject: Merge branch 'nd/attr-match-optim' X-Git-Tag: v1.8.1-rc0~105 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/70d1825749ba1528af507e27ba5f8a660a5ede3d?ds=inline;hp=-c Merge branch 'nd/attr-match-optim' Trivial and obvious optimization for finding attributes that match a given path. * nd/attr-match-optim: attr: avoid searching for basename on every match attr: avoid strlen() on every match --- 70d1825749ba1528af507e27ba5f8a660a5ede3d diff --combined attr.c index 887a9ae46b,e7caee4ddd..179886cc4b --- a/attr.c +++ b/attr.c @@@ -277,6 -277,7 +277,7 @@@ static struct match_attr *parse_attr_li static struct attr_stack { struct attr_stack *prev; char *origin; + size_t originlen; unsigned num_matches; unsigned alloc; struct match_attr **attrs; @@@ -306,7 -307,7 +307,7 @@@ static void free_attr_elem(struct attr_ } static const char *builtin_attr[] = { - "[attr]binary -diff -text", + "[attr]binary -diff -merge -text", NULL, }; @@@ -352,11 -353,8 +353,11 @@@ static struct attr_stack *read_attr_fro char buf[2048]; int lineno = 0; - if (!fp) + if (!fp) { + if (errno != ENOENT && errno != ENOTDIR) + warn_on_inaccessible(path); return NULL; + } res = xcalloc(1, sizeof(*res)); while (fgets(buf, sizeof(buf), fp)) handle_attr_line(res, buf, path, ++lineno, macro_ok); @@@ -500,7 -498,6 +501,7 @@@ static int git_attr_system(void static void bootstrap_attr_stack(void) { struct attr_stack *elem; + char *xdg_attributes_file; if (attr_stack) return; @@@ -519,10 -516,6 +520,10 @@@ } } + if (!git_attributes_file) { + home_config_paths(NULL, &xdg_attributes_file, "attributes"); + git_attributes_file = xdg_attributes_file; + } if (git_attributes_file) { elem = read_attr_from_file(git_attributes_file, 1); if (elem) { @@@ -535,6 -528,7 +536,7 @@@ if (!is_bare_repository() || direction == GIT_ATTR_INDEX) { elem = read_attr(GITATTRIBUTES_FILE, 1); elem->origin = xstrdup(""); + elem->originlen = 0; elem->prev = attr_stack; attr_stack = elem; debug_push(elem); @@@ -628,7 -622,7 +630,7 @@@ static void prepare_attr_stack(const ch strbuf_addstr(&pathbuf, GITATTRIBUTES_FILE); elem = read_attr(pathbuf.buf, 0); strbuf_setlen(&pathbuf, cp - path); - elem->origin = strbuf_detach(&pathbuf, NULL); + elem->origin = strbuf_detach(&pathbuf, &elem->originlen); elem->prev = attr_stack; attr_stack = elem; debug_push(elem); @@@ -645,13 -639,11 +647,11 @@@ } static int path_matches(const char *pathname, int pathlen, + const char *basename, const char *pattern, const char *base, int baselen) { if (!strchr(pattern, '/')) { - /* match basename */ - const char *basename = strrchr(pathname, '/'); - basename = basename ? basename + 1 : pathname; return (fnmatch_icase(pattern, basename, 0) == 0); } /* @@@ -693,7 -685,8 +693,8 @@@ static int fill_one(const char *what, s return rem; } - static int fill(const char *path, int pathlen, struct attr_stack *stk, int rem) + static int fill(const char *path, int pathlen, const char *basename, + struct attr_stack *stk, int rem) { int i; const char *base = stk->origin ? stk->origin : ""; @@@ -702,8 -695,8 +703,8 @@@ struct match_attr *a = stk->attrs[i]; if (a->is_macro) continue; - if (path_matches(path, pathlen, - a->u.pattern, base, strlen(base))) + if (path_matches(path, pathlen, basename, + a->u.pattern, base, stk->originlen)) rem = fill_one("fill", a, rem); } return rem; @@@ -741,15 -734,19 +742,19 @@@ static void collect_all_attrs(const cha { struct attr_stack *stk; int i, pathlen, rem; + const char *basename; prepare_attr_stack(path); for (i = 0; i < attr_nr; i++) check_all_attr[i].value = ATTR__UNKNOWN; + basename = strrchr(path, '/'); + basename = basename ? basename + 1 : path; + pathlen = strlen(path); rem = attr_nr; for (stk = attr_stack; 0 < rem && stk; stk = stk->prev) - rem = fill(path, pathlen, stk, rem); + rem = fill(path, pathlen, basename, stk, rem); } int git_check_attr(const char *path, int num, struct git_attr_check *check)