Git fork

odb: get rid of `the_repository` when handling submodule sources

The "--recursive" flag for git-grep(1) allows users to grep for a string
across submodule boundaries. To make this work we add each submodule's
object sources to our own object database so that the objects can be
accessed directly.

The infrastructure for this depends on a global string list of submodule
paths. The caller is expected to call `add_submodule_odb_by_path()` for
each source and the object database will then eventually register all
submodule sources via `do_oid_object_info_extended()` in case it isn't
able to look up a specific object.

This reliance on global state is of course suboptimal with regards to
our libification efforts.

Refactor the logic so that the list of submodule sources is instead
tracked in the object database itself. This allows us to lose the
condition of `r == the_repository` before registering submodule sources
as we only ever add submodule sources to `the_repository` anyway. As
such, behaviour before and after this refactoring should always be the
same.

Rename the functions accordingly.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Patrick Steinhardt and committed by
Junio C Hamano
fc28a8a8 7eafd447

+50 -43
+2 -1
builtin/grep.c
··· 505 505 * lazily registered as alternates when needed (and except in an 506 506 * unexpected code interaction, it won't be needed). 507 507 */ 508 - add_submodule_odb_by_path(subrepo->objects->sources->path); 508 + odb_add_submodule_source_by_path(the_repository->objects, 509 + subrepo->objects->sources->path); 509 510 obj_read_unlock(); 510 511 511 512 memcpy(&subopt, opt, sizeof(subopt));
+31 -6
odb.c
··· 24 24 #include "strbuf.h" 25 25 #include "strvec.h" 26 26 #include "submodule.h" 27 + #include "trace2.h" 27 28 #include "write-or-die.h" 28 29 29 30 KHASH_INIT(odb_path_map, const char * /* key: odb_path */, ··· 469 470 return source; 470 471 } 471 472 473 + void odb_add_submodule_source_by_path(struct object_database *odb, 474 + const char *path) 475 + { 476 + string_list_insert(&odb->submodule_source_paths, path); 477 + } 478 + 472 479 static void fill_alternate_refs_command(struct child_process *cmd, 473 480 const char *repo_path) 474 481 { ··· 623 630 624 631 int fetch_if_missing = 1; 625 632 633 + static int register_all_submodule_sources(struct object_database *odb) 634 + { 635 + int ret = odb->submodule_source_paths.nr; 636 + 637 + for (size_t i = 0; i < odb->submodule_source_paths.nr; i++) 638 + odb_add_to_alternates_memory(odb, 639 + odb->submodule_source_paths.items[i].string); 640 + if (ret) { 641 + string_list_clear(&odb->submodule_source_paths, 0); 642 + trace2_data_intmax("submodule", odb->repo, 643 + "register_all_submodule_sources/registered", ret); 644 + if (git_env_bool("GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB", 0)) 645 + BUG("register_all_submodule_sources() called"); 646 + } 647 + return ret; 648 + } 649 + 626 650 static int do_oid_object_info_extended(struct repository *r, 627 651 const struct object_id *oid, 628 652 struct object_info *oi, unsigned flags) ··· 676 700 } 677 701 678 702 /* 679 - * If r is the_repository, this might be an attempt at 680 - * accessing a submodule object as if it were in the_repository 681 - * (having called add_submodule_odb() on that submodule's ODB). 682 - * If any such ODBs exist, register them and try again. 703 + * This might be an attempt at accessing a submodule object as 704 + * if it were in main object store (having called 705 + * `odb_add_submodule_source_by_path()` on that submodule's 706 + * ODB). If any such ODBs exist, register them and try again. 683 707 */ 684 - if (r == the_repository && 685 - register_all_submodule_odb_as_alternates()) 708 + if (register_all_submodule_sources(r->objects)) 686 709 /* We added some alternates; retry */ 687 710 continue; 688 711 ··· 968 991 INIT_LIST_HEAD(&o->packed_git_mru); 969 992 hashmap_init(&o->pack_map, pack_map_entry_cmp, NULL, 0); 970 993 pthread_mutex_init(&o->replace_mutex, NULL); 994 + string_list_init_dup(&o->submodule_source_paths); 971 995 return o; 972 996 } 973 997 ··· 1017 1041 o->packed_git = NULL; 1018 1042 1019 1043 hashmap_clear(&o->pack_map); 1044 + string_list_clear(&o->submodule_source_paths, 0); 1020 1045 }
+15
odb.h
··· 6 6 #include "list.h" 7 7 #include "oidset.h" 8 8 #include "oidmap.h" 9 + #include "string-list.h" 9 10 #include "thread-utils.h" 10 11 11 12 struct oidmap; ··· 165 166 * packs. 166 167 */ 167 168 unsigned packed_git_initialized : 1; 169 + 170 + /* 171 + * Submodule source paths that will be added as additional sources to 172 + * allow lookup of submodule objects via the main object database. 173 + */ 174 + struct string_list submodule_source_paths; 168 175 }; 169 176 170 177 struct object_database *odb_new(struct repository *repo); ··· 190 197 void odb_restore_primary_source(struct object_database *odb, 191 198 struct odb_source *restore_source, 192 199 const char *old_path); 200 + 201 + /* 202 + * Call odb_add_submodule_source_by_path() to add the submodule at the given 203 + * path to a list. The object stores of all submodules in that list will be 204 + * added as additional sources in the object store when looking up objects. 205 + */ 206 + void odb_add_submodule_source_by_path(struct object_database *odb, 207 + const char *path); 193 208 194 209 /* 195 210 * Iterate through all alternates of the database and execute the provided
+2 -1
submodule-config.c
··· 810 810 repo_get_oid(repo, GITMODULES_HEAD, &oid) >= 0) { 811 811 config_source.blob = oidstr = xstrdup(oid_to_hex(&oid)); 812 812 if (repo != the_repository) 813 - add_submodule_odb_by_path(repo->objects->sources->path); 813 + odb_add_submodule_source_by_path(the_repository->objects, 814 + repo->objects->sources->path); 814 815 } else { 815 816 goto out; 816 817 }
-26
submodule.c
··· 31 31 #include "commit-reach.h" 32 32 #include "read-cache-ll.h" 33 33 #include "setup.h" 34 - #include "trace2.h" 35 34 36 35 static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF; 37 36 static int initialized_fetch_ref_tips; ··· 174 173 { 175 174 if (add_file_to_index(istate, GITMODULES_FILE, 0)) 176 175 die(_("staging updated .gitmodules failed")); 177 - } 178 - 179 - static struct string_list added_submodule_odb_paths = STRING_LIST_INIT_DUP; 180 - 181 - void add_submodule_odb_by_path(const char *path) 182 - { 183 - string_list_insert(&added_submodule_odb_paths, path); 184 - } 185 - 186 - int register_all_submodule_odb_as_alternates(void) 187 - { 188 - int i; 189 - int ret = added_submodule_odb_paths.nr; 190 - 191 - for (i = 0; i < added_submodule_odb_paths.nr; i++) 192 - odb_add_to_alternates_memory(the_repository->objects, 193 - added_submodule_odb_paths.items[i].string); 194 - if (ret) { 195 - string_list_clear(&added_submodule_odb_paths, 0); 196 - trace2_data_intmax("submodule", the_repository, 197 - "register_all_submodule_odb_as_alternates/registered", ret); 198 - if (git_env_bool("GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB", 0)) 199 - BUG("register_all_submodule_odb_as_alternates() called"); 200 - } 201 - return ret; 202 176 } 203 177 204 178 void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
-9
submodule.h
··· 105 105 int bad_to_remove_submodule(const char *path, unsigned flags); 106 106 107 107 /* 108 - * Call add_submodule_odb_by_path() to add the submodule at the given 109 - * path to a list. When register_all_submodule_odb_as_alternates() is 110 - * called, the object stores of all submodules in that list will be 111 - * added as alternates in the_repository. 112 - */ 113 - void add_submodule_odb_by_path(const char *path); 114 - int register_all_submodule_odb_as_alternates(void); 115 - 116 - /* 117 108 * Checks if there are submodule changes in a..b. If a is the null OID, 118 109 * checks b and all its ancestors instead. 119 110 */