@@ -329,106 +329,6 @@ static int grep_config(const char *var, const char *value, void *cb)
329
329
return 0 ;
330
330
}
331
331
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
-
432
332
static void * lock_and_read_sha1_file (const unsigned char * sha1 , enum object_type * type , unsigned long * size )
433
333
{
434
334
void * data ;
@@ -621,25 +521,24 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int
621
521
static int grep_tree (struct grep_opt * opt , const struct pathspec * pathspec ,
622
522
struct tree_desc * tree , struct strbuf * base , int tn_len )
623
523
{
624
- int hit = 0 ;
524
+ int hit = 0 , matched = 0 ;
625
525
struct name_entry entry ;
626
526
int old_baselen = base -> len ;
627
527
628
528
while (tree_entry (tree , & entry )) {
629
529
int te_len = tree_entry_len (entry .path , entry .sha1 );
630
530
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
+ }
632
538
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 );
639
540
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 )) {
643
542
hit |= grep_sha1 (opt , entry .sha1 , base -> buf , tn_len );
644
543
}
645
544
else if (S_ISDIR (entry .mode )) {
@@ -652,6 +551,8 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
652
551
if (!data )
653
552
die ("unable to read tree (%s)" ,
654
553
sha1_to_hex (entry .sha1 ));
554
+
555
+ strbuf_addch (base , '/' );
655
556
init_tree_desc (& sub , data , size );
656
557
hit |= grep_tree (opt , pathspec , & sub , base , tn_len );
657
558
free (data );
@@ -1058,6 +959,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
1058
959
paths [1 ] = NULL ;
1059
960
}
1060
961
init_pathspec (& pathspec , paths );
962
+ pathspec .max_depth = opt .max_depth ;
963
+ pathspec .recursive = 1 ;
1061
964
1062
965
if (show_in_pager && (cached || list .nr ))
1063
966
die ("--open-files-in-pager only works on the worktree" );
0 commit comments