@@ -329,106 +329,6 @@ static int grep_config(const char *var, const char *value, void *cb)
329329 return 0 ;
330330}
331331
332- /*
333- * Return non-zero if max_depth is negative or path has no more then max_depth
334- * slashes.
335- */
336- static int accept_subdir (const char * path , int max_depth )
337- {
338- if (max_depth < 0 )
339- return 1 ;
340-
341- while ((path = strchr (path , '/' )) != NULL ) {
342- max_depth -- ;
343- if (max_depth < 0 )
344- return 0 ;
345- path ++ ;
346- }
347- return 1 ;
348- }
349-
350- /*
351- * Return non-zero if name is a subdirectory of match and is not too deep.
352- */
353- static int is_subdir (const char * name , int namelen ,
354- const char * match , int matchlen , int max_depth )
355- {
356- if (matchlen > namelen || strncmp (name , match , matchlen ))
357- return 0 ;
358-
359- if (name [matchlen ] == '\0' ) /* exact match */
360- return 1 ;
361-
362- if (!matchlen || match [matchlen - 1 ] == '/' || name [matchlen ] == '/' )
363- return accept_subdir (name + matchlen + 1 , max_depth );
364-
365- return 0 ;
366- }
367-
368- /*
369- * git grep pathspecs are somewhat different from diff-tree pathspecs;
370- * pathname wildcards are allowed.
371- */
372- static int pathspec_matches (const char * * paths , const char * name , int max_depth )
373- {
374- int namelen , i ;
375- if (!paths || !* paths )
376- return accept_subdir (name , max_depth );
377- namelen = strlen (name );
378- for (i = 0 ; paths [i ]; i ++ ) {
379- const char * match = paths [i ];
380- int matchlen = strlen (match );
381- const char * cp , * meta ;
382-
383- if (is_subdir (name , namelen , match , matchlen , max_depth ))
384- return 1 ;
385- if (!fnmatch (match , name , 0 ))
386- return 1 ;
387- if (name [namelen - 1 ] != '/' )
388- continue ;
389-
390- /* We are being asked if the directory ("name") is worth
391- * descending into.
392- *
393- * Find the longest leading directory name that does
394- * not have metacharacter in the pathspec; the name
395- * we are looking at must overlap with that directory.
396- */
397- for (cp = match , meta = NULL ; cp - match < matchlen ; cp ++ ) {
398- char ch = * cp ;
399- if (ch == '*' || ch == '[' || ch == '?' ) {
400- meta = cp ;
401- break ;
402- }
403- }
404- if (!meta )
405- meta = cp ; /* fully literal */
406-
407- if (namelen <= meta - match ) {
408- /* Looking at "Documentation/" and
409- * the pattern says "Documentation/howto/", or
410- * "Documentation/diff*.txt". The name we
411- * have should match prefix.
412- */
413- if (!memcmp (match , name , namelen ))
414- return 1 ;
415- continue ;
416- }
417-
418- if (meta - match < namelen ) {
419- /* Looking at "Documentation/howto/" and
420- * the pattern says "Documentation/h*";
421- * match up to "Do.../h"; this avoids descending
422- * into "Documentation/technical/".
423- */
424- if (!memcmp (match , name , meta - match ))
425- return 1 ;
426- continue ;
427- }
428- }
429- return 0 ;
430- }
431-
432332static void * lock_and_read_sha1_file (const unsigned char * sha1 , enum object_type * type , unsigned long * size )
433333{
434334 void * data ;
@@ -621,25 +521,24 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int
621521static int grep_tree (struct grep_opt * opt , const struct pathspec * pathspec ,
622522 struct tree_desc * tree , struct strbuf * base , int tn_len )
623523{
624- int hit = 0 ;
524+ int hit = 0 , matched = 0 ;
625525 struct name_entry entry ;
626526 int old_baselen = base -> len ;
627527
628528 while (tree_entry (tree , & entry )) {
629529 int te_len = tree_entry_len (entry .path , entry .sha1 );
630530
631- strbuf_add (base , entry .path , te_len );
531+ if (matched != 2 ) {
532+ matched = tree_entry_interesting (& entry , base , tn_len , pathspec );
533+ if (matched == -1 )
534+ break ; /* no more matches */
535+ if (!matched )
536+ continue ;
537+ }
632538
633- if (S_ISDIR (entry .mode ))
634- /* Match "abc/" against pathspec to
635- * decide if we want to descend into "abc"
636- * directory.
637- */
638- strbuf_addch (base , '/' );
539+ strbuf_add (base , entry .path , te_len );
639540
640- if (!pathspec_matches (pathspec -> raw , base -> buf + tn_len , opt -> max_depth ))
641- ;
642- else if (S_ISREG (entry .mode )) {
541+ if (S_ISREG (entry .mode )) {
643542 hit |= grep_sha1 (opt , entry .sha1 , base -> buf , tn_len );
644543 }
645544 else if (S_ISDIR (entry .mode )) {
@@ -652,6 +551,8 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
652551 if (!data )
653552 die ("unable to read tree (%s)" ,
654553 sha1_to_hex (entry .sha1 ));
554+
555+ strbuf_addch (base , '/' );
655556 init_tree_desc (& sub , data , size );
656557 hit |= grep_tree (opt , pathspec , & sub , base , tn_len );
657558 free (data );
@@ -1058,6 +959,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
1058959 paths [1 ] = NULL ;
1059960 }
1060961 init_pathspec (& pathspec , paths );
962+ pathspec .max_depth = opt .max_depth ;
963+ pathspec .recursive = 1 ;
1061964
1062965 if (show_in_pager && (cached || list .nr ))
1063966 die ("--open-files-in-pager only works on the worktree" );
0 commit comments