summaryrefslogtreecommitdiff
path: root/builtin/grep.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/grep.c')
-rw-r--r--builtin/grep.c90
1 files changed, 55 insertions, 35 deletions
diff --git a/builtin/grep.c b/builtin/grep.c
index 71df52a333..ae2d5bbafc 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 2006 Junio C Hamano
*/
+#define USE_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
#include "repository.h"
#include "config.h"
@@ -393,18 +394,22 @@ static void run_pager(struct grep_opt *opt, const char *prefix)
exit(status);
}
-static int grep_cache(struct grep_opt *opt, struct repository *repo,
+static int grep_cache(struct grep_opt *opt,
const struct pathspec *pathspec, int cached);
static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
struct tree_desc *tree, struct strbuf *base, int tn_len,
- int check_attr, struct repository *repo);
+ int check_attr);
-static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
+static int grep_submodule(struct grep_opt *opt,
const struct pathspec *pathspec,
const struct object_id *oid,
- const char *filename, const char *path)
+ const char *filename, const char *path, int cached)
{
- struct repository submodule;
+ struct repository subrepo;
+ struct repository *superproject = opt->repo;
+ const struct submodule *sub = submodule_from_path(superproject,
+ &null_oid, path);
+ struct grep_opt subopt;
int hit;
/*
@@ -420,12 +425,12 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
return 0;
}
- if (repo_submodule_init(&submodule, superproject, path)) {
+ if (repo_submodule_init(&subrepo, superproject, sub)) {
grep_read_unlock();
return 0;
}
- repo_read_gitmodules(&submodule);
+ repo_read_gitmodules(&subrepo);
/*
* NEEDSWORK: This adds the submodule's object directory to the list of
@@ -437,9 +442,12 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
* store is no longer global and instead is a member of the repository
* object.
*/
- add_to_alternates_memory(submodule.objects->objectdir);
+ add_to_alternates_memory(subrepo.objects->odb->path);
grep_read_unlock();
+ memcpy(&subopt, opt, sizeof(subopt));
+ subopt.repo = &subrepo;
+
if (oid) {
struct object *object;
struct tree_desc tree;
@@ -450,7 +458,8 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
object = parse_object_or_die(oid, oid_to_hex(oid));
grep_read_lock();
- data = read_object_with_reference(&object->oid, tree_type,
+ data = read_object_with_reference(&subrepo,
+ &object->oid, tree_type,
&size, NULL);
grep_read_unlock();
@@ -461,21 +470,22 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
strbuf_addch(&base, '/');
init_tree_desc(&tree, data, size);
- hit = grep_tree(opt, pathspec, &tree, &base, base.len,
- object->type == OBJ_COMMIT, &submodule);
+ hit = grep_tree(&subopt, pathspec, &tree, &base, base.len,
+ object->type == OBJ_COMMIT);
strbuf_release(&base);
free(data);
} else {
- hit = grep_cache(opt, &submodule, pathspec, 1);
+ hit = grep_cache(&subopt, pathspec, cached);
}
- repo_clear(&submodule);
+ repo_clear(&subrepo);
return hit;
}
-static int grep_cache(struct grep_opt *opt, struct repository *repo,
+static int grep_cache(struct grep_opt *opt,
const struct pathspec *pathspec, int cached)
{
+ struct repository *repo = opt->repo;
int hit = 0;
int nr;
struct strbuf name = STRBUF_INIT;
@@ -513,7 +523,8 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo,
}
} else if (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&
submodule_path_match(repo->index, pathspec, name.buf, NULL)) {
- hit |= grep_submodule(opt, repo, pathspec, NULL, ce->name, ce->name);
+ hit |= grep_submodule(opt, pathspec, NULL, ce->name,
+ ce->name, cached);
} else {
continue;
}
@@ -535,8 +546,9 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo,
static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
struct tree_desc *tree, struct strbuf *base, int tn_len,
- int check_attr, struct repository *repo)
+ int check_attr)
{
+ struct repository *repo = opt->repo;
int hit = 0;
enum interesting match = entry_not_interesting;
struct name_entry entry;
@@ -553,7 +565,8 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
if (match != all_entries_interesting) {
strbuf_addstr(&name, base->buf + tn_len);
- match = tree_entry_interesting(&entry, &name,
+ match = tree_entry_interesting(repo->index,
+ &entry, &name,
0, pathspec);
strbuf_setlen(&name, name_base_len);
@@ -566,7 +579,7 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
strbuf_add(base, entry.path, te_len);
if (S_ISREG(entry.mode)) {
- hit |= grep_oid(opt, entry.oid, base->buf, tn_len,
+ hit |= grep_oid(opt, &entry.oid, base->buf, tn_len,
check_attr ? base->buf + tn_len : NULL);
} else if (S_ISDIR(entry.mode)) {
enum object_type type;
@@ -574,19 +587,20 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
void *data;
unsigned long size;
- data = lock_and_read_oid_file(entry.oid, &type, &size);
+ data = lock_and_read_oid_file(&entry.oid, &type, &size);
if (!data)
die(_("unable to read tree (%s)"),
- oid_to_hex(entry.oid));
+ oid_to_hex(&entry.oid));
strbuf_addch(base, '/');
init_tree_desc(&sub, data, size);
hit |= grep_tree(opt, pathspec, &sub, base, tn_len,
- check_attr, repo);
+ check_attr);
free(data);
} else if (recurse_submodules && S_ISGITLINK(entry.mode)) {
- hit |= grep_submodule(opt, repo, pathspec, entry.oid,
- base->buf, base->buf + tn_len);
+ hit |= grep_submodule(opt, pathspec, &entry.oid,
+ base->buf, base->buf + tn_len,
+ 1); /* ignored */
}
strbuf_setlen(base, old_baselen);
@@ -612,7 +626,8 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
int hit, len;
grep_read_lock();
- data = read_object_with_reference(&obj->oid, tree_type,
+ data = read_object_with_reference(opt->repo,
+ &obj->oid, tree_type,
&size, NULL);
grep_read_unlock();
@@ -627,7 +642,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
}
init_tree_desc(&tree, data, size);
hit = grep_tree(opt, pathspec, &tree, &base, base.len,
- obj->type == OBJ_COMMIT, the_repository);
+ obj->type == OBJ_COMMIT);
strbuf_release(&base);
free(data);
return hit;
@@ -644,12 +659,12 @@ 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(the_repository, list->objects[i].item,
+ real_obj = deref_tag(opt->repo, list->objects[i].item,
NULL, 0);
/* load the gitmodules file for this rev */
if (recurse_submodules) {
- submodule_free(the_repository);
+ submodule_free(opt->repo);
gitmodules_config_oid(&real_obj->oid);
}
if (grep_object(opt, pathspec, real_obj, list->objects[i].name,
@@ -674,9 +689,9 @@ static int grep_directory(struct grep_opt *opt, const struct pathspec *pathspec,
if (exc_std)
setup_standard_excludes(&dir);
- fill_directory(&dir, &the_index, pathspec);
+ fill_directory(&dir, opt->repo->index, pathspec);
for (i = 0; i < dir.nr; i++) {
- if (!dir_path_match(&the_index, dir.entries[i], pathspec, 0, NULL))
+ if (!dir_path_match(opt->repo->index, dir.entries[i], pathspec, 0, NULL))
continue;
hit |= grep_file(opt, dir.entries[i]->name);
if (hit && opt->status_only)
@@ -943,6 +958,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
/* die the same way as if we did it at the beginning */
setup_git_directory();
}
+ /* Ignore --recurse-submodules if --no-index is given or implied */
+ if (!use_index)
+ recurse_submodules = 0;
/*
* skip a -- separator; we know it cannot be
@@ -1014,7 +1032,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
break;
}
- if (get_oid_with_context(arg, GET_OID_RECORD_PATH,
+ if (get_oid_with_context(the_repository, arg,
+ GET_OID_RECORD_PATH,
&oid, &oc)) {
if (seen_dashdash)
die(_("unable to resolve revision: %s"), arg);
@@ -1094,13 +1113,13 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
strbuf_addf(&buf, "+/%s%s",
strcmp("less", pager) ? "" : "*",
opt.pattern_list->pattern);
- string_list_append(&path_list, buf.buf);
- strbuf_detach(&buf, NULL);
+ string_list_append(&path_list,
+ strbuf_detach(&buf, NULL));
}
}
- if (recurse_submodules && (!use_index || untracked))
- die(_("option not supported with --recurse-submodules"));
+ if (recurse_submodules && untracked)
+ die(_("--untracked not supported with --recurse-submodules"));
if (!show_in_pager && !opt.status_only)
setup_pager();
@@ -1117,7 +1136,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
if (!cached)
setup_work_tree();
- hit = grep_cache(&opt, the_repository, &pathspec, cached);
+ hit = grep_cache(&opt, &pathspec, cached);
} else {
if (cached)
die(_("both --cached and trees are given"));
@@ -1131,5 +1150,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
run_pager(&opt, prefix);
clear_pathspec(&pathspec);
free_grep_patterns(&opt);
+ grep_destroy();
return !hit;
}