grep --no-index: allow use of "git grep" outside a git repository
Just like some people wanted diff features that are not found in other people's diff implementations outside of a git repository and added --no-index mode to the command, this adds --no-index mode to the "git grep" command. Also, inside a git repository, --no-index mode allows you to grep in untracked (but not ignored) files. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano committed
Jan 15, 2010 at 12:52 UTC
308162372d0aa202ff45743e02253e20a4fac4d7
2 files changed
+78
builtin-grep.c
+26
@@ -14,6 +14,7 @@
14
#include "userdiff.h"
15
#include "grep.h"
16
#include "quote.h"
17
+#include "dir.h"
18
19
static char const * const grep_usage[] = {
20
"git grep [options] [-e] <pattern> [<rev>...] [[--] path...]",
@@ -320,6 +321,21 @@ static int grep_object(struct grep_opt *opt, const char **paths,
321
die("unable to grep from object of type %s", typename(obj->type));
322
}
323
324
+static int grep_directory(struct grep_opt *opt, const char **paths)
325
+{
326
+ struct dir_struct dir;
327
+ int i, hit = 0;
328
+
329
+ memset(&dir, 0, sizeof(dir));
330
+ setup_standard_excludes(&dir);
331
+
332
+ fill_directory(&dir, paths);
333
+ for (i = 0; i < dir.nr; i++)
334
+ hit |= grep_file(opt, dir.entries[i]->name);
335
+ free_grep_patterns(opt);
336
+ return hit;
337
+}
338
+
339
static int context_callback(const struct option *opt, const char *arg,
340
int unset)
341
{
@@ -418,6 +434,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
434
struct option options[] = {
435
OPT_BOOLEAN(0, "cached", &cached,
436
"search in index instead of in the work tree"),
437
+ OPT_BOOLEAN(0, "index", &use_index,
438
+ "--no-index finds in contents not managed by git"),
439
OPT_GROUP(""),
440
OPT_BOOLEAN('v', "invert-match", &opt.invert,
441
"show non-matching lines"),
@@ -591,6 +609,14 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
609
paths[1] = NULL;
610
}
611
612
+ if (!use_index) {
613
+ if (cached)
614
+ die("--cached cannot be used with --no-index.");
615
+ if (list.nr)
616
+ die("--no-index cannot be used with revs.");
617
+ return !grep_directory(&opt, paths);
618
+ }
619
+
620
if (!list.nr) {
621
if (!cached)
622
setup_work_tree();
t/t7002-grep.sh
+52
@@ -426,4 +426,56 @@ test_expect_success 'grep -Fi' '
426
test_cmp expected actual
427
'
428
429
+test_expect_success 'outside of git repository' '
430
+ rm -fr non &&
431
+ mkdir -p non/git/sub &&
432
+ echo hello >non/git/file1 &&
433
+ echo world >non/git/sub/file2 &&
434
+ echo ".*o*" >non/git/.gitignore &&
435
+ {
436
+ echo file1:hello &&
437
+ echo sub/file2:world
438
+ } >non/expect.full &&
439
+ echo file2:world >non/expect.sub
440
+ (
441
+ GIT_CEILING_DIRECTORIES="$(pwd)/non/git" &&
442
+ export GIT_CEILING_DIRECTORIES &&
443
+ cd non/git &&
444
+ test_must_fail git grep o &&
445
+ git grep --no-index o >../actual.full &&
446
+ test_cmp ../expect.full ../actual.full
447
+ cd sub &&
448
+ test_must_fail git grep o &&
449
+ git grep --no-index o >../../actual.sub &&
450
+ test_cmp ../../expect.sub ../../actual.sub
451
+ )
452
+'
453
+
454
+test_expect_success 'inside git repository but with --no-index' '
455
+ rm -fr is &&
456
+ mkdir -p is/git/sub &&
457
+ echo hello >is/git/file1 &&
458
+ echo world >is/git/sub/file2 &&
459
+ echo ".*o*" >is/git/.gitignore &&
460
+ {
461
+ echo file1:hello &&
462
+ echo sub/file2:world
463
+ } >is/expect.full &&
464
+ : >is/expect.empty &&
465
+ echo file2:world >is/expect.sub
466
+ (
467
+ cd is/git &&
468
+ git init &&
469
+ test_must_fail git grep o >../actual.full &&
470
+ test_cmp ../expect.empty ../actual.full &&
471
+ git grep --no-index o >../actual.full &&
472
+ test_cmp ../expect.full ../actual.full &&
473
+ cd sub &&
474
+ test_must_fail git grep o >../../actual.sub &&
475
+ test_cmp ../../expect.empty ../../actual.sub &&
476
+ git grep --no-index o >../../actual.sub &&
477
+ test_cmp ../../expect.sub ../../actual.sub
478
+ )
479
+'
480
+
481
test_done