]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'jc/grep-f-relative-to-cwd'
authorJunio C Hamano <gitster@pobox.com>
Tue, 7 Nov 2023 01:26:43 +0000 (10:26 +0900)
committerJunio C Hamano <gitster@pobox.com>
Tue, 7 Nov 2023 01:26:43 +0000 (10:26 +0900)
"cd sub && git grep -f patterns" tried to read "patterns" file at
the top level of the working tree; it has been corrected to read
"sub/patterns" instead.

* jc/grep-f-relative-to-cwd:
  grep: -f <path> is relative to $cwd

1  2 
builtin/grep.c
t/t7810-grep.sh

diff --combined builtin/grep.c
index b71222330add858a8ae6ce0363666e85c04a5cef,8851184eab206992327804a163d5d63317484532..fe78d4c98b13b578a09de344d6a56d2316a8cb00
@@@ -4,6 -4,7 +4,7 @@@
   * Copyright (c) 2006 Junio C Hamano
   */
  #include "builtin.h"
+ #include "abspath.h"
  #include "gettext.h"
  #include "hex.h"
  #include "repository.h"
@@@ -812,14 -813,20 +813,20 @@@ static int file_callback(const struct o
  {
        struct grep_opt *grep_opt = opt->value;
        int from_stdin;
+       const char *filename = arg;
        FILE *patterns;
        int lno = 0;
        struct strbuf sb = STRBUF_INIT;
  
        BUG_ON_OPT_NEG(unset);
  
-       from_stdin = !strcmp(arg, "-");
-       patterns = from_stdin ? stdin : fopen(arg, "r");
+       if (!*filename)
+               ; /* leave it as-is */
+       else
+               filename = prefix_filename_except_for_dash(grep_prefix, filename);
+       from_stdin = !strcmp(filename, "-");
+       patterns = from_stdin ? stdin : fopen(filename, "r");
        if (!patterns)
                die_errno(_("cannot open '%s'"), arg);
        while (strbuf_getline(&sb, patterns) == 0) {
        if (!from_stdin)
                fclose(patterns);
        strbuf_release(&sb);
+       if (filename != arg)
+               free((void *)filename);
        return 0;
  }
  
@@@ -924,8 -933,9 +933,8 @@@ int cmd_grep(int argc, const char **arg
                         N_("process binary files with textconv filters")),
                OPT_SET_INT('r', "recursive", &opt.max_depth,
                            N_("search in subdirectories (default)"), -1),
 -              { OPTION_INTEGER, 0, "max-depth", &opt.max_depth, N_("depth"),
 -                      N_("descend at most <depth> levels"), PARSE_OPT_NONEG,
 -                      NULL, 1 },
 +              OPT_INTEGER_F(0, "max-depth", &opt.max_depth,
 +                      N_("descend at most <n> levels"), PARSE_OPT_NONEG),
                OPT_GROUP(""),
                OPT_SET_INT('E', "extended-regexp", &opt.pattern_type_option,
                            N_("use extended POSIX regular expressions"),
                OPT_CALLBACK_F(0, "and", &opt, NULL,
                        N_("combine patterns specified with -e"),
                        PARSE_OPT_NOARG | PARSE_OPT_NONEG, and_callback),
 -              OPT_BOOL(0, "or", &dummy, ""),
 +              OPT_BOOL_F(0, "or", &dummy, "", PARSE_OPT_NONEG),
                OPT_CALLBACK_F(0, "not", &opt, NULL, "",
                        PARSE_OPT_NOARG | PARSE_OPT_NONEG, not_callback),
                OPT_CALLBACK_F('(', NULL, &opt, NULL, "",
diff --combined t/t7810-grep.sh
index 84838c0fe1bd36c7cd647301a580f5a3fe41ef85,91ac66935f5b955781caf15af64e104dd1119445..1caaf12430929a2c01e09dad4270947e480ec614
@@@ -808,6 -808,19 +808,19 @@@ test_expect_success 'grep -f, ignore em
        test_cmp expected actual
  '
  
+ test_expect_success 'grep -f, use cwd relative file' '
+       test_when_finished "git rm -f sub/dir/file" &&
+       mkdir -p sub/dir &&
+       echo hit >sub/dir/file &&
+       git add sub/dir/file &&
+       echo hit >sub/dir/pattern &&
+       echo miss >pattern &&
+       (
+               cd sub/dir && git grep -f pattern file
+       ) &&
+       git -C sub/dir grep -f pattern file
+ '
  cat >expected <<EOF
  y:y yy
  --
@@@ -1234,33 -1247,6 +1247,33 @@@ test_expect_success 'outside of git rep
        )
  '
  
 +test_expect_success 'no repository with path outside $cwd' '
 +      test_when_finished rm -fr non &&
 +      rm -fr non &&
 +      mkdir -p non/git/sub non/tig &&
 +      (
 +              GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
 +              export GIT_CEILING_DIRECTORIES &&
 +              cd non/git &&
 +              test_expect_code 128 git grep --no-index search .. 2>error &&
 +              grep "is outside the directory tree" error
 +      ) &&
 +      (
 +              GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
 +              export GIT_CEILING_DIRECTORIES &&
 +              cd non/git &&
 +              test_expect_code 128 git grep --no-index search ../tig 2>error &&
 +              grep "is outside the directory tree" error
 +      ) &&
 +      (
 +              GIT_CEILING_DIRECTORIES="$(pwd)/non" &&
 +              export GIT_CEILING_DIRECTORIES &&
 +              cd non/git &&
 +              test_expect_code 128 git grep --no-index search ../non 2>error &&
 +              grep "no such path in the working tree" error
 +      )
 +'
 +
  test_expect_success 'inside git repository but with --no-index' '
        rm -fr is &&
        mkdir -p is/git/sub &&