grep: add repository to OID grep sources

Record the repository whenever an OID grep source is created, and teach the worker threads to explicitly provide the repository when accessing objects. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Reviewed-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Tan committed Aug 16, 2021 at 14:09 UTC 0693806bf82fb76347e226d8fc5e69077c0a3df5
3 files changed +27 -12
builtin/grep.c
+6 -9
@@ -349,7 +349,7 @@ static int grep_oid(struct grep_opt *opt, const struct object_id *oid,
349 struct grep_source gs;
350
351 grep_source_name(opt, filename, tree_name_len, &pathbuf);
352 - grep_source_init_oid(&gs, pathbuf.buf, path, oid);
352 + grep_source_init_oid(&gs, pathbuf.buf, path, oid, opt->repo);
353 strbuf_release(&pathbuf);
354
355 if (num_threads > 1) {
@@ -462,14 +462,11 @@ static int grep_submodule(struct grep_opt *opt,
462 repo_read_gitmodules(subrepo, 0);
463
464 /*
465 - * NEEDSWORK: This adds the submodule's object directory to the list of
466 - * alternates for the single in-memory object store. This has some bad
467 - * consequences for memory (processed objects will never be freed) and
468 - * performance (this increases the number of pack files git has to pay
469 - * attention to, to the sum of the number of pack files in all the
470 - * repositories processed so far). This can be removed once the object
471 - * store is no longer global and instead is a member of the repository
472 - * object.
465 + * All code paths tested by test code no longer need submodule ODBs to
466 + * be added as alternates, but add it to the list just in case.
467 + * Submodule ODBs added through add_submodule_odb_by_path() will be
468 + * lazily registered as alternates when needed (and except in an
469 + * unexpected code interaction, it won't be needed).
470 */
471 add_submodule_odb_by_path(subrepo->objects->odb->path);
472 obj_read_unlock();
grep.c
+5 -2
@@ -1863,7 +1863,8 @@ void grep_source_init_file(struct grep_source *gs, const char *name,
1863 }
1864
1865 void grep_source_init_oid(struct grep_source *gs, const char *name,
1866 - const char *path, const struct object_id *oid)
1866 + const char *path, const struct object_id *oid,
1867 + struct repository *repo)
1868 {
1869 gs->type = GREP_SOURCE_OID;
1870 gs->name = xstrdup_or_null(name);
@@ -1872,6 +1873,7 @@ void grep_source_init_oid(struct grep_source *gs, const char *name,
1873 gs->size = 0;
1874 gs->driver = NULL;
1875 gs->identifier = oiddup(oid);
1876 + gs->repo = repo;
1877 }
1878
1879 void grep_source_clear(struct grep_source *gs)
@@ -1900,7 +1902,8 @@ static int grep_source_load_oid(struct grep_source *gs)
1902 {
1903 enum object_type type;
1904
1903 - gs->buf = read_object_file(gs->identifier, &type, &gs->size);
1905 + gs->buf = repo_read_object_file(gs->repo, gs->identifier, &type,
1906 + &gs->size);
1907 if (!gs->buf)
1908 return error(_("'%s': unable to read %s"),
1909 gs->name,
grep.h
+16 -1
@@ -120,7 +120,20 @@ struct grep_opt {
120 struct grep_pat *header_list;
121 struct grep_pat **header_tail;
122 struct grep_expr *pattern_expression;
123 +
124 + /*
125 + * NEEDSWORK: See if we can remove this field, because the repository
126 + * should probably be per-source. That is, grep.c functions using this
127 + * field should probably start using "repo" in "struct grep_source"
128 + * instead.
129 + *
130 + * This is potentially the cause of at least one bug - "git grep"
131 + * ignoring the textconv attributes from submodules. See [1] for more
132 + * information.
133 + * [1] https://lore.kernel.org/git/CAHd-oW5iEQarYVxEXoTG-ua2zdoybTrSjCBKtO0YT292fm0NQQ@mail.gmail.com/
134 + */
135 struct repository *repo;
136 +
137 const char *prefix;
138 int prefix_length;
139 regex_t regexp;
@@ -187,6 +200,7 @@ struct grep_source {
200 GREP_SOURCE_BUF,
201 } type;
202 void *identifier;
203 + struct repository *repo; /* if GREP_SOURCE_OID */
204
205 char *buf;
206 unsigned long size;
@@ -198,7 +212,8 @@ struct grep_source {
212 void grep_source_init_file(struct grep_source *gs, const char *name,
213 const char *path);
214 void grep_source_init_oid(struct grep_source *gs, const char *name,
201 - const char *path, const struct object_id *oid);
215 + const char *path, const struct object_id *oid,
216 + struct repository *repo);
217 void grep_source_clear_data(struct grep_source *gs);
218 void grep_source_clear(struct grep_source *gs);
219 void grep_source_load_driver(struct grep_source *gs,