Skip to content

Commit f0eaf63

Browse files
peffgitster
authored andcommitted
sha1-file: use an object_directory for the main object dir
Our handling of alternate object directories is needlessly different from the main object directory. As a result, many places in the code basically look like this: do_something(r->objects->objdir); for (odb = r->objects->alt_odb_list; odb; odb = odb->next) do_something(odb->path); That gets annoying when do_something() is non-trivial, and we've resorted to gross hacks like creating fake alternates (see find_short_object_filename()). Instead, let's give each raw_object_store a unified list of object_directory structs. The first will be the main store, and everything after is an alternate. Very few callers even care about the distinction, and can just loop over the whole list (and those who care can just treat the first element differently). A few observations: - we don't need r->objects->objectdir anymore, and can just mechanically convert that to r->objects->odb->path - object_directory's path field needs to become a real pointer rather than a FLEX_ARRAY, in order to fill it with expand_base_dir() - we'll call prepare_alt_odb() earlier in many functions (i.e., outside of the loop). This may result in us calling it even when our function would be satisfied looking only at the main odb. But this doesn't matter in practice. It's not a very expensive operation in the first place, and in the majority of cases it will be a noop. We call it already (and cache its results) in prepare_packed_git(), and we'll generally check packs before loose objects. So essentially every program is going to call it immediately once per program. Arguably we should just prepare_alt_odb() immediately upon setting up the repository's object directory, which would save us sprinkling calls throughout the code base (and forgetting to do so has been a source of subtle bugs in the past). But I've stopped short of that here, since there are already a lot of other moving parts in this patch. - Most call sites just get shorter. The check_and_freshen() functions are an exception, because they have entry points to handle local and nonlocal directories separately. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f3f043a commit f0eaf63

11 files changed

+90
-147
lines changed

builtin/fsck.c

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -725,13 +725,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
725725
for_each_loose_object(mark_loose_for_connectivity, NULL, 0);
726726
for_each_packed_object(mark_packed_for_connectivity, NULL, 0);
727727
} else {
728-
struct object_directory *alt_odb_list;
729-
730-
fsck_object_dir(get_object_directory());
731-
732728
prepare_alt_odb(the_repository);
733-
alt_odb_list = the_repository->objects->alt_odb_list;
734-
for (odb = alt_odb_list; odb; odb = odb->next)
729+
for (odb = the_repository->objects->odb; odb; odb = odb->next)
735730
fsck_object_dir(odb->path);
736731

737732
if (check_full) {
@@ -834,13 +829,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
834829
struct child_process commit_graph_verify = CHILD_PROCESS_INIT;
835830
const char *verify_argv[] = { "commit-graph", "verify", NULL, NULL, NULL };
836831

837-
commit_graph_verify.argv = verify_argv;
838-
commit_graph_verify.git_cmd = 1;
839-
if (run_command(&commit_graph_verify))
840-
errors_found |= ERROR_COMMIT_GRAPH;
841-
842832
prepare_alt_odb(the_repository);
843-
for (odb = the_repository->objects->alt_odb_list; odb; odb = odb->next) {
833+
for (odb = the_repository->objects->odb; odb; odb = odb->next) {
844834
child_process_init(&commit_graph_verify);
845835
commit_graph_verify.argv = verify_argv;
846836
commit_graph_verify.git_cmd = 1;
@@ -855,13 +845,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
855845
struct child_process midx_verify = CHILD_PROCESS_INIT;
856846
const char *midx_argv[] = { "multi-pack-index", "verify", NULL, NULL, NULL };
857847

858-
midx_verify.argv = midx_argv;
859-
midx_verify.git_cmd = 1;
860-
if (run_command(&midx_verify))
861-
errors_found |= ERROR_COMMIT_GRAPH;
862-
863848
prepare_alt_odb(the_repository);
864-
for (odb = the_repository->objects->alt_odb_list; odb; odb = odb->next) {
849+
for (odb = the_repository->objects->odb; odb; odb = odb->next) {
865850
child_process_init(&midx_verify);
866851
midx_verify.argv = midx_argv;
867852
midx_verify.git_cmd = 1;

builtin/grep.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
441441
* object.
442442
*/
443443
grep_read_lock();
444-
add_to_alternates_memory(submodule.objects->objectdir);
444+
add_to_alternates_memory(submodule.objects->odb->path);
445445
grep_read_unlock();
446446

447447
if (oid) {

commit-graph.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ static void prepare_commit_graph_one(struct repository *r, const char *obj_dir)
231231
static int prepare_commit_graph(struct repository *r)
232232
{
233233
struct object_directory *odb;
234-
char *obj_dir;
235234
int config_value;
236235

237236
if (r->objects->commit_graph_attempted)
@@ -252,10 +251,8 @@ static int prepare_commit_graph(struct repository *r)
252251
if (!commit_graph_compatible(r))
253252
return 0;
254253

255-
obj_dir = r->objects->objectdir;
256-
prepare_commit_graph_one(r, obj_dir);
257254
prepare_alt_odb(r);
258-
for (odb = r->objects->alt_odb_list;
255+
for (odb = r->objects->odb;
259256
!r->objects->commit_graph && odb;
260257
odb = odb->next)
261258
prepare_commit_graph_one(r, odb->path);

environment.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,9 @@ const char *get_git_work_tree(void)
274274

275275
char *get_object_directory(void)
276276
{
277-
if (!the_repository->objects->objectdir)
277+
if (!the_repository->objects->odb)
278278
BUG("git environment hasn't been setup");
279-
return the_repository->objects->objectdir;
279+
return the_repository->objects->odb->path;
280280
}
281281

282282
int odb_mkstemp(struct strbuf *temp_filename, const char *pattern)

object-store.h

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,14 @@ struct object_directory {
2424
* Path to the alternative object store. If this is a relative path,
2525
* it is relative to the current working directory.
2626
*/
27-
char path[FLEX_ARRAY];
27+
char *path;
2828
};
29+
2930
void prepare_alt_odb(struct repository *r);
3031
char *compute_alternate_path(const char *path, struct strbuf *err);
3132
typedef int alt_odb_fn(struct object_directory *, void *);
3233
int foreach_alt_odb(alt_odb_fn, void*);
3334

34-
/*
35-
* Allocate a "struct alternate_object_database" but do _not_ actually
36-
* add it to the list of alternates.
37-
*/
38-
struct object_directory *alloc_alt_odb(const char *dir);
39-
4035
/*
4136
* Add the directory to the on-disk alternates file; the new entry will also
4237
* take effect in the current process.
@@ -80,17 +75,21 @@ struct multi_pack_index;
8075

8176
struct raw_object_store {
8277
/*
83-
* Path to the repository's object store.
84-
* Cannot be NULL after initialization.
78+
* Set of all object directories; the main directory is first (and
79+
* cannot be NULL after initialization). Subsequent directories are
80+
* alternates.
8581
*/
86-
char *objectdir;
82+
struct object_directory *odb;
83+
struct object_directory **odb_tail;
84+
int loaded_alternates;
8785

88-
/* Path to extra alternate object database if not NULL */
86+
/*
87+
* A list of alternate object directories loaded from the environment;
88+
* this should not generally need to be accessed directly, but will
89+
* populate the "odb" list when prepare_alt_odb() is run.
90+
*/
8991
char *alternate_db;
9092

91-
struct object_directory *alt_odb_list;
92-
struct object_directory **alt_odb_tail;
93-
9493
/*
9594
* Objects that should be substituted by other objects
9695
* (see git-replace(1)).

object.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -482,26 +482,26 @@ struct raw_object_store *raw_object_store_new(void)
482482
return o;
483483
}
484484

485-
static void free_alt_odb(struct object_directory *odb)
485+
static void free_object_directory(struct object_directory *odb)
486486
{
487+
free(odb->path);
487488
oid_array_clear(&odb->loose_objects_cache);
488489
free(odb);
489490
}
490491

491-
static void free_alt_odbs(struct raw_object_store *o)
492+
static void free_object_directories(struct raw_object_store *o)
492493
{
493-
while (o->alt_odb_list) {
494+
while (o->odb) {
494495
struct object_directory *next;
495496

496-
next = o->alt_odb_list->next;
497-
free_alt_odb(o->alt_odb_list);
498-
o->alt_odb_list = next;
497+
next = o->odb->next;
498+
free_object_directory(o->odb);
499+
o->odb = next;
499500
}
500501
}
501502

502503
void raw_object_store_clear(struct raw_object_store *o)
503504
{
504-
FREE_AND_NULL(o->objectdir);
505505
FREE_AND_NULL(o->alternate_db);
506506

507507
oidmap_free(o->replace_map, 1);
@@ -511,8 +511,9 @@ void raw_object_store_clear(struct raw_object_store *o)
511511
o->commit_graph = NULL;
512512
o->commit_graph_attempted = 0;
513513

514-
free_alt_odbs(o);
515-
o->alt_odb_tail = NULL;
514+
free_object_directories(o);
515+
o->odb_tail = NULL;
516+
o->loaded_alternates = 0;
516517

517518
INIT_LIST_HEAD(&o->packed_git_mru);
518519
close_all_packs(o);

packfile.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -970,12 +970,12 @@ static void prepare_packed_git(struct repository *r)
970970

971971
if (r->objects->packed_git_initialized)
972972
return;
973-
prepare_multi_pack_index_one(r, r->objects->objectdir, 1);
974-
prepare_packed_git_one(r, r->objects->objectdir, 1);
973+
975974
prepare_alt_odb(r);
976-
for (odb = r->objects->alt_odb_list; odb; odb = odb->next) {
977-
prepare_multi_pack_index_one(r, odb->path, 0);
978-
prepare_packed_git_one(r, odb->path, 0);
975+
for (odb = r->objects->odb; odb; odb = odb->next) {
976+
int local = (odb == r->objects->odb);
977+
prepare_multi_pack_index_one(r, odb->path, local);
978+
prepare_packed_git_one(r, odb->path, local);
979979
}
980980
rearrange_packed_git(r);
981981

path.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ static void adjust_git_path(const struct repository *repo,
383383
strbuf_splice(buf, 0, buf->len,
384384
repo->index_file, strlen(repo->index_file));
385385
else if (dir_prefix(base, "objects"))
386-
replace_dir(buf, git_dir_len + 7, repo->objects->objectdir);
386+
replace_dir(buf, git_dir_len + 7, repo->objects->odb->path);
387387
else if (git_hooks_path && dir_prefix(base, "hooks"))
388388
replace_dir(buf, git_dir_len + 5, git_hooks_path);
389389
else if (repo->different_commondir)

repository.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,14 @@ void repo_set_gitdir(struct repository *repo,
6363
free(old_gitdir);
6464

6565
repo_set_commondir(repo, o->commondir);
66-
expand_base_dir(&repo->objects->objectdir, o->object_dir,
66+
67+
if (!repo->objects->odb) {
68+
repo->objects->odb = xcalloc(1, sizeof(*repo->objects->odb));
69+
repo->objects->odb_tail = &repo->objects->odb->next;
70+
}
71+
expand_base_dir(&repo->objects->odb->path, o->object_dir,
6772
repo->commondir, "objects");
73+
6874
free(repo->objects->alternate_db);
6975
repo->objects->alternate_db = xstrdup_or_null(o->alternate_db);
7076
expand_base_dir(&repo->graft_file, o->graft_file,

0 commit comments

Comments
 (0)