@@ -277,6 +277,7 @@ static struct match_attr *parse_attr_line(const char *line, const char *src,
277277static struct attr_stack {
278278 struct attr_stack * prev ;
279279 char * origin ;
280+ size_t originlen ;
280281 unsigned num_matches ;
281282 unsigned alloc ;
282283 struct match_attr * * attrs ;
@@ -535,6 +536,7 @@ static void bootstrap_attr_stack(void)
535536 if (!is_bare_repository () || direction == GIT_ATTR_INDEX ) {
536537 elem = read_attr (GITATTRIBUTES_FILE , 1 );
537538 elem -> origin = xstrdup ("" );
539+ elem -> originlen = 0 ;
538540 elem -> prev = attr_stack ;
539541 attr_stack = elem ;
540542 debug_push (elem );
@@ -628,7 +630,7 @@ static void prepare_attr_stack(const char *path)
628630 strbuf_addstr (& pathbuf , GITATTRIBUTES_FILE );
629631 elem = read_attr (pathbuf .buf , 0 );
630632 strbuf_setlen (& pathbuf , cp - path );
631- elem -> origin = strbuf_detach (& pathbuf , NULL );
633+ elem -> origin = strbuf_detach (& pathbuf , & elem -> originlen );
632634 elem -> prev = attr_stack ;
633635 attr_stack = elem ;
634636 debug_push (elem );
@@ -645,13 +647,11 @@ static void prepare_attr_stack(const char *path)
645647}
646648
647649static int path_matches (const char * pathname , int pathlen ,
650+ const char * basename ,
648651 const char * pattern ,
649652 const char * base , int baselen )
650653{
651654 if (!strchr (pattern , '/' )) {
652- /* match basename */
653- const char * basename = strrchr (pathname , '/' );
654- basename = basename ? basename + 1 : pathname ;
655655 return (fnmatch_icase (pattern , basename , 0 ) == 0 );
656656 }
657657 /*
@@ -693,7 +693,8 @@ static int fill_one(const char *what, struct match_attr *a, int rem)
693693 return rem ;
694694}
695695
696- static int fill (const char * path , int pathlen , struct attr_stack * stk , int rem )
696+ static int fill (const char * path , int pathlen , const char * basename ,
697+ struct attr_stack * stk , int rem )
697698{
698699 int i ;
699700 const char * base = stk -> origin ? stk -> origin : "" ;
@@ -702,8 +703,8 @@ static int fill(const char *path, int pathlen, struct attr_stack *stk, int rem)
702703 struct match_attr * a = stk -> attrs [i ];
703704 if (a -> is_macro )
704705 continue ;
705- if (path_matches (path , pathlen ,
706- a -> u .pattern , base , strlen ( base ) ))
706+ if (path_matches (path , pathlen , basename ,
707+ a -> u .pattern , base , stk -> originlen ))
707708 rem = fill_one ("fill" , a , rem );
708709 }
709710 return rem ;
@@ -741,15 +742,19 @@ static void collect_all_attrs(const char *path)
741742{
742743 struct attr_stack * stk ;
743744 int i , pathlen , rem ;
745+ const char * basename ;
744746
745747 prepare_attr_stack (path );
746748 for (i = 0 ; i < attr_nr ; i ++ )
747749 check_all_attr [i ].value = ATTR__UNKNOWN ;
748750
751+ basename = strrchr (path , '/' );
752+ basename = basename ? basename + 1 : path ;
753+
749754 pathlen = strlen (path );
750755 rem = attr_nr ;
751756 for (stk = attr_stack ; 0 < rem && stk ; stk = stk -> prev )
752- rem = fill (path , pathlen , stk , rem );
757+ rem = fill (path , pathlen , basename , stk , rem );
753758}
754759
755760int git_check_attr (const char * path , int num , struct git_attr_check * check )
0 commit comments