Code

Merge branch 'cb/maint-1.6.3-grep-relative-up' into maint
authorJunio C Hamano <gitster@pobox.com>
Sun, 13 Sep 2009 08:24:20 +0000 (01:24 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 13 Sep 2009 08:24:20 +0000 (01:24 -0700)
* cb/maint-1.6.3-grep-relative-up:
  grep: accept relative paths outside current working directory
  grep: fix exit status if external_grep() punts

Conflicts:
t/t7002-grep.sh

1  2 
builtin-grep.c
grep.h
t/t7002-grep.sh

diff --cc builtin-grep.c
index f477659100fdc63bff5938b4c96f28eaefc07460,eda2c884870abde5f9d943259916de45d9425a6c..fd450bc16e56a634b14cfa33f77e5192412643d8
  #include "tag.h"
  #include "tree-walk.h"
  #include "builtin.h"
 +#include "parse-options.h"
 +#include "userdiff.h"
  #include "grep.h"
+ #include "quote.h"
  
  #ifndef NO_EXTERNAL_GREP
  #ifdef __unix__
@@@ -676,93 -570,9 +667,94 @@@ int cmd_grep(int argc, const char **arg
        struct object_array list = { 0, 0, NULL };
        const char **paths = NULL;
        int i;
 +      int dummy;
 +      struct option options[] = {
 +              OPT_BOOLEAN(0, "cached", &cached,
 +                      "search in index instead of in the work tree"),
 +              OPT_GROUP(""),
 +              OPT_BOOLEAN('v', "invert-match", &opt.invert,
 +                      "show non-matching lines"),
 +              OPT_BIT('i', "ignore-case", &opt.regflags,
 +                      "case insensitive matching", REG_ICASE),
 +              OPT_BOOLEAN('w', "word-regexp", &opt.word_regexp,
 +                      "match patterns only at word boundaries"),
 +              OPT_SET_INT('a', "text", &opt.binary,
 +                      "process binary files as text", GREP_BINARY_TEXT),
 +              OPT_SET_INT('I', NULL, &opt.binary,
 +                      "don't match patterns in binary files",
 +                      GREP_BINARY_NOMATCH),
 +              OPT_GROUP(""),
 +              OPT_BIT('E', "extended-regexp", &opt.regflags,
 +                      "use extended POSIX regular expressions", REG_EXTENDED),
 +              OPT_NEGBIT('G', "basic-regexp", &opt.regflags,
 +                      "use basic POSIX regular expressions (default)",
 +                      REG_EXTENDED),
 +              OPT_BOOLEAN('F', "fixed-strings", &opt.fixed,
 +                      "interpret patterns as fixed strings"),
 +              OPT_GROUP(""),
 +              OPT_BOOLEAN('n', NULL, &opt.linenum, "show line numbers"),
 +              OPT_NEGBIT('h', NULL, &opt.pathname, "don't show filenames", 1),
 +              OPT_BIT('H', NULL, &opt.pathname, "show filenames", 1),
 +              OPT_NEGBIT(0, "full-name", &opt.relative,
 +                      "show filenames relative to top directory", 1),
 +              OPT_BOOLEAN('l', "files-with-matches", &opt.name_only,
 +                      "show only filenames instead of matching lines"),
 +              OPT_BOOLEAN(0, "name-only", &opt.name_only,
 +                      "synonym for --files-with-matches"),
 +              OPT_BOOLEAN('L', "files-without-match",
 +                      &opt.unmatch_name_only,
 +                      "show only the names of files without match"),
 +              OPT_BOOLEAN('z', "null", &opt.null_following_name,
 +                      "print NUL after filenames"),
 +              OPT_BOOLEAN('c', "count", &opt.count,
 +                      "show the number of matches instead of matching lines"),
 +              OPT_SET_INT(0, "color", &opt.color, "highlight matches", 1),
 +              OPT_GROUP(""),
 +              OPT_CALLBACK('C', NULL, &opt, "n",
 +                      "show <n> context lines before and after matches",
 +                      context_callback),
 +              OPT_INTEGER('B', NULL, &opt.pre_context,
 +                      "show <n> context lines before matches"),
 +              OPT_INTEGER('A', NULL, &opt.post_context,
 +                      "show <n> context lines after matches"),
 +              OPT_NUMBER_CALLBACK(&opt, "shortcut for -C NUM",
 +                      context_callback),
 +              OPT_BOOLEAN('p', "show-function", &opt.funcname,
 +                      "show a line with the function name before matches"),
 +              OPT_GROUP(""),
 +              OPT_CALLBACK('f', NULL, &opt, "file",
 +                      "read patterns from file", file_callback),
 +              { OPTION_CALLBACK, 'e', NULL, &opt, "pattern",
 +                      "match <pattern>", PARSE_OPT_NONEG, pattern_callback },
 +              { OPTION_CALLBACK, 0, "and", &opt, NULL,
 +                "combine patterns specified with -e",
 +                PARSE_OPT_NOARG | PARSE_OPT_NONEG, and_callback },
 +              OPT_BOOLEAN(0, "or", &dummy, ""),
 +              { OPTION_CALLBACK, 0, "not", &opt, NULL, "",
 +                PARSE_OPT_NOARG | PARSE_OPT_NONEG, not_callback },
 +              { OPTION_CALLBACK, '(', NULL, &opt, NULL, "",
 +                PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,
 +                open_callback },
 +              { OPTION_CALLBACK, ')', NULL, &opt, NULL, "",
 +                PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_NODASH,
 +                close_callback },
 +              OPT_BOOLEAN(0, "all-match", &opt.all_match,
 +                      "show only matches from files that match all patterns"),
 +              OPT_GROUP(""),
 +#if NO_EXTERNAL_GREP
 +              OPT_BOOLEAN(0, "ext-grep", &external_grep_allowed,
 +                      "allow calling of grep(1) (ignored by this build)"),
 +#else
 +              OPT_BOOLEAN(0, "ext-grep", &external_grep_allowed,
 +                      "allow calling of grep(1) (default)"),
 +#endif
 +              { OPTION_CALLBACK, 0, "help-all", &options, NULL, "show usage",
 +                PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback },
 +              OPT_END()
 +      };
  
        memset(&opt, 0, sizeof(opt));
+       opt.prefix = prefix;
        opt.prefix_length = (prefix && *prefix) ? strlen(prefix) : 0;
        opt.relative = 1;
        opt.pathname = 1;
diff --cc grep.h
index f00db0e40273c7cca1695ddc6be00921f9da8ef4,5b767c931c0fec250d4dff74f6ef72c0abea16af..5581363c4ddb988830f9c9b776b057821107f92a
--- 1/grep.h
--- 2/grep.h
+++ b/grep.h
@@@ -59,17 -59,18 +59,18 @@@ struct grep_opt 
        struct grep_pat *pattern_list;
        struct grep_pat **pattern_tail;
        struct grep_expr *pattern_expression;
+       const char *prefix;
        int prefix_length;
        regex_t regexp;
 -      unsigned linenum:1;
 -      unsigned invert:1;
 -      unsigned status_only:1;
 -      unsigned name_only:1;
 -      unsigned unmatch_name_only:1;
 -      unsigned count:1;
 -      unsigned word_regexp:1;
 -      unsigned fixed:1;
 -      unsigned all_match:1;
 +      int linenum;
 +      int invert;
 +      int status_only;
 +      int name_only;
 +      int unmatch_name_only;
 +      int count;
 +      int word_regexp;
 +      int fixed;
 +      int all_match;
  #define GREP_BINARY_DEFAULT   0
  #define GREP_BINARY_NOMATCH   1
  #define GREP_BINARY_TEXT      2
diff --cc t/t7002-grep.sh
index b13aa7e89ad51566979ab674baa2ac36c7e33da6,fe87834fbeb22dfe21fabbbfb56f7c73558de2b2..6ca11d71465aa609232614bbbd360955869e0776
@@@ -243,40 -212,21 +243,57 @@@ test_expect_success 'grep with CE_VALI
        git checkout t/t
  '
  
 +cat >expected <<EOF
 +hello.c=#include <stdio.h>
 +hello.c:      return 0;
 +EOF
 +
 +test_expect_success 'grep -p with userdiff' '
 +      git config diff.custom.funcname "^#" &&
 +      echo "hello.c diff=custom" >.gitattributes &&
 +      git grep -p return >actual &&
 +      test_cmp expected actual
 +'
 +
 +cat >expected <<EOF
 +hello.c=int main(int argc, const char **argv)
 +hello.c:      return 0;
 +EOF
 +
 +test_expect_success 'grep -p' '
 +      rm -f .gitattributes &&
 +      git grep -p return >actual &&
 +      test_cmp expected actual
 +'
 +
 +cat >expected <<EOF
 +hello.c-#include <stdio.h>
 +hello.c=int main(int argc, const char **argv)
 +hello.c-{
 +hello.c-      printf("Hello world.\n");
 +hello.c:      return 0;
 +EOF
 +
 +test_expect_success 'grep -p -B5' '
 +      git grep -p -B5 return >actual &&
 +      test_cmp expected actual
 +'
 +
+ test_expect_success 'grep from a subdirectory to search wider area (1)' '
+       mkdir -p s &&
+       (
+               cd s && git grep "x x x" ..
+       )
+ '
+ test_expect_success 'grep from a subdirectory to search wider area (2)' '
+       mkdir -p s &&
+       (
+               cd s || exit 1
+               ( git grep xxyyzz .. >out ; echo $? >status )
+               ! test -s out &&
+               test 1 = $(cat status)
+       )
+ '
  test_done