From: Junio C Hamano Date: Wed, 5 Oct 2011 01:40:41 +0000 (-0700) Subject: Merge branch 'jc/maint-grep-untracked-exclude' into jc/grep-untracked-exclude X-Git-Tag: v1.7.8-rc0~71^2~1 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=dbfae86a7b0bf9f9a4f37dbc916e8d26a5f9d51c;p=git.git Merge branch 'jc/maint-grep-untracked-exclude' into jc/grep-untracked-exclude * jc/maint-grep-untracked-exclude: grep: teach --untracked and --exclude-standard options grep --no-index: don't use git standard exclusions grep: do not use --index in the short usage output Conflicts: Documentation/git-grep.txt builtin/grep.c --- dbfae86a7b0bf9f9a4f37dbc916e8d26a5f9d51c diff --cc Documentation/git-grep.txt index e44a4988b,6269007b9..15d6711d4 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@@ -19,12 -18,11 +19,12 @@@ SYNOPSI [-z | --null] [-c | --count] [--all-match] [-q | --quiet] [--max-depth ] - [--color | --no-color] + [--color[=] | --no-color] [-A ] [-B ] [-C ] [-f ] [-e] - [--and|--or|--not|(|)|-e ...] [...] - [--] [...] + [--and|--or|--not|(|)|-e ...] - [--cached | --no-index | ...] ++ [ [--exclude-standard] [--cached | --no-index | --untracked] | ...] + [--] [...] DESCRIPTION ----------- @@@ -45,11 -33,21 +45,24 @@@ grep.extendedRegexp: OPTIONS ------- --cached:: - Instead of searching in the working tree files, check - the blobs registered in the index file. + Instead of searching tracked files in the working tree, search + blobs registered in the index file. + +--no-index:: - Search files in the current directory, not just those tracked by git. ++ Search files in the current directory that is not managed by git. + + --untracked:: + In addition to searching in the tracked files in the working + tree, search also in untracked files. + + --no-exclude-standard:: + Also search in ignored files by not honoring the `.gitignore` + mechanism. Only useful with `--untracked`. + + --exclude-standard:: + Do not pay attention to ignored files specified via the `.gitignore` + mechanism. Only useful when searching files in the current directory + with `--no-index`. -a:: --text:: diff --cc builtin/grep.c index 1c359c267,2da6bc61b..5e6d3c335 --- a/builtin/grep.c +++ b/builtin/grep.c @@@ -615,42 -643,20 +615,44 @@@ static int grep_object(struct grep_opt free(data); return hit; } - die("unable to grep from object of type %s", typename(obj->type)); + die(_("unable to grep from object of type %s"), typename(obj->type)); +} + +static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec, + const struct object_array *list) +{ + unsigned int i; + int hit = 0; + const unsigned int nr = list->nr; + + for (i = 0; i < nr; i++) { + struct object *real_obj; + real_obj = deref_tag(list->objects[i].item, NULL, 0); + if (grep_object(opt, pathspec, real_obj, list->objects[i].name)) { + hit = 1; + if (opt->status_only) + break; + } + } + return hit; } - static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec) -static int grep_directory(struct grep_opt *opt, const char **paths, int exc_std) ++static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec, ++ int exc_std) { struct dir_struct dir; int i, hit = 0; memset(&dir, 0, sizeof(dir)); - setup_standard_excludes(&dir); + if (exc_std) + setup_standard_excludes(&dir); - fill_directory(&dir, paths); + fill_directory(&dir, pathspec->raw); for (i = 0; i < dir.nr; i++) { + const char *name = dir.entries[i]->name; + int namelen = strlen(name); + if (!match_pathspec_depth(pathspec, name, namelen, 0, NULL)) + continue; hit |= grep_file(opt, dir.entries[i]->name); if (hit && opt->status_only) break; @@@ -750,27 -751,15 +752,27 @@@ static int help_callback(const struct o int cmd_grep(int argc, const char **argv, const char *prefix) { int hit = 0; - int cached = 0; + int cached = 0, untracked = 0, opt_exclude = -1; int seen_dashdash = 0; int external_grep_allowed__ignored; + const char *show_in_pager = NULL, *default_pager = "dummy"; struct grep_opt opt; - struct object_array list = { 0, 0, NULL }; + struct object_array list = OBJECT_ARRAY_INIT; const char **paths = NULL; + struct pathspec pathspec; + struct string_list path_list = STRING_LIST_INIT_NODUP; int i; int dummy; - int nongit = 0, use_index = 1; + int use_index = 1; + enum { + pattern_type_unspecified = 0, + pattern_type_bre, + pattern_type_ere, + pattern_type_fixed, + pattern_type_pcre, + }; + int pattern_type = pattern_type_unspecified; + struct option options[] = { OPT_BOOLEAN(0, "cached", &cached, "search in index instead of in the work tree"), @@@ -1017,42 -948,33 +1024,45 @@@ verify_filename(prefix, argv[j]); } - if (i < argc) - paths = get_pathspec(prefix, argv + i); - else if (prefix) { - paths = xcalloc(2, sizeof(const char *)); - paths[0] = prefix; - paths[1] = NULL; + paths = get_pathspec(prefix, argv + i); + init_pathspec(&pathspec, paths); + pathspec.max_depth = opt.max_depth; + pathspec.recursive = 1; + + if (show_in_pager && (cached || list.nr)) + die(_("--open-files-in-pager only works on the worktree")); + + if (show_in_pager && opt.pattern_list && !opt.pattern_list->next) { + const char *pager = path_list.items[0].string; + int len = strlen(pager); + + if (len > 4 && is_dir_sep(pager[len - 5])) + pager += len - 4; + + if (!strcmp("less", pager) || !strcmp("vi", pager)) { + struct strbuf buf = STRBUF_INIT; + strbuf_addf(&buf, "+/%s%s", + strcmp("less", pager) ? "" : "*", + opt.pattern_list->pattern); + string_list_append(&path_list, buf.buf); + strbuf_detach(&buf, NULL); + } } + if (!show_in_pager) + setup_pager(); + + if (!use_index && (untracked || cached)) - die("--cached or --untracked cannot be used with --no-index."); ++ die(_("--cached or --untracked cannot be used with --no-index.")); - if (!use_index) { - if (cached) - die(_("--cached cannot be used with --no-index.")); + if (!use_index || untracked) { - int hit; + int use_exclude = (opt_exclude < 0) ? use_index : !!opt_exclude; if (list.nr) - die(_("--no-index cannot be used with revs.")); - hit = grep_directory(&opt, &pathspec); - die("--no-index or --untracked cannot be used with revs."); - hit = grep_directory(&opt, paths, use_exclude); - if (use_threads) - hit |= wait_all(); - return !hit; - } - - if (0 <= opt_exclude) - die("--exclude or --no-exclude cannot be used for tracked contents."); - - if (!list.nr) { - int hit; ++ die(_("--no-index or --untracked cannot be used with revs.")); ++ hit = grep_directory(&opt, &pathspec, use_exclude); ++ } else if (0 <= opt_exclude) { ++ die(_("--exclude or --no-exclude cannot be used for tracked contents.")); + } else if (!list.nr) { if (!cached) setup_work_tree(); diff --cc t/t7810-grep.sh index 0d600163c,bf7877d93..81263b785 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@@ -583,9 -484,13 +599,13 @@@ test_expect_success 'inside git reposit { echo file1:hello && echo sub/file2:world + } >is/expect.unignored && + { + echo ".gitignore:.*o*" && + cat is/expect.unignored } >is/expect.full && : >is/expect.empty && - echo file2:world >is/expect.sub + echo file2:world >is/expect.sub && ( cd is/git && git init &&