Documentation/git.txt: improve documentation of 'GIT_TRACE*' variables
[gitweb.git] / builtin / grep.c
index 03bc442e3f96ba12ec389f0fc40349a57e073dc7..c86a142f308d614daefd459fd9f9ddebe03f4cb8 100644 (file)
@@ -361,9 +361,7 @@ static void run_pager(struct grep_opt *opt, const char *prefix)
                argv[i] = path_list->items[i].string;
        argv[path_list->nr] = NULL;
 
-       if (prefix && chdir(prefix))
-               die(_("Failed to chdir: %s"), prefix);
-       status = run_command_v_opt(argv, RUN_USING_SHELL);
+       status = run_command_v_opt_cd_env(argv, RUN_USING_SHELL, prefix, NULL);
        if (status)
                exit(status);
        free(argv);
@@ -379,7 +377,7 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int
                const struct cache_entry *ce = active_cache[nr];
                if (!S_ISREG(ce->ce_mode))
                        continue;
-               if (!match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, NULL))
+               if (!ce_path_match(ce, pathspec, NULL))
                        continue;
                /*
                 * If CE_VALID is on, we assume worktree file and its cache entry
@@ -458,10 +456,10 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
 }
 
 static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
-                      struct object *obj, const char *name)
+                      struct object *obj, const char *name, struct object_context *oc)
 {
        if (obj->type == OBJ_BLOB)
-               return grep_sha1(opt, obj->sha1, name, 0, NULL);
+               return grep_sha1(opt, obj->sha1, name, 0, oc ? oc->path : NULL);
        if (obj->type == OBJ_COMMIT || obj->type == OBJ_TREE) {
                struct tree_desc tree;
                void *data;
@@ -503,7 +501,7 @@ static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
        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)) {
+               if (grep_object(opt, pathspec, real_obj, list->objects[i].name, list->objects[i].context)) {
                        hit = 1;
                        if (opt->status_only)
                                break;
@@ -524,9 +522,7 @@ static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec,
 
        fill_directory(&dir, pathspec);
        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))
+               if (!dir_path_match(dir.entries[i], pathspec, 0, NULL))
                        continue;
                hit |= grep_file(opt, dir.entries[i]->name);
                if (hit && opt->status_only)
@@ -658,6 +654,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                OPT_SET_INT('I', NULL, &opt.binary,
                        N_("don't match patterns in binary files"),
                        GREP_BINARY_NOMATCH),
+               OPT_BOOL(0, "textconv", &opt.allow_textconv,
+                        N_("process binary files with textconv filters")),
                { OPTION_INTEGER, 0, "max-depth", &opt.max_depth, N_("depth"),
                        N_("descend at most <depth> levels"), PARSE_OPT_NONEG,
                        NULL, 1 },
@@ -817,12 +815,13 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
        for (i = 0; i < argc; i++) {
                const char *arg = argv[i];
                unsigned char sha1[20];
+               struct object_context oc;
                /* Is it a rev? */
-               if (!get_sha1(arg, sha1)) {
+               if (!get_sha1_with_context(arg, 0, sha1, &oc)) {
                        struct object *object = parse_object_or_die(sha1, arg);
                        if (!seen_dashdash)
                                verify_non_filename(prefix, arg);
-                       add_object_array(object, arg, &list);
+                       add_object_array_with_context(object, arg, &list, xmemdupz(&oc, sizeof(struct object_context)));
                        continue;
                }
                if (!strcmp(arg, "--")) {
@@ -873,6 +872,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                if (len > 4 && is_dir_sep(pager[len - 5]))
                        pager += len - 4;
 
+               if (opt.ignore_case && !strcmp("less", pager))
+                       string_list_append(&path_list, "-I");
+
                if (!strcmp("less", pager) || !strcmp("vi", pager)) {
                        struct strbuf buf = STRBUF_INIT;
                        strbuf_addf(&buf, "+/%s%s",