It took some time to do fixes in such a long series, mostl of my time spent in rebasing and being extra careful about selecting the right commit to edit. Based on feedback so far I have queued the changes below. The changes are also available at https://github.com/stefanbeller/git/tree/object-store-v2 I do not plan on sending out this series today, as I would want to wait a couple of days between resending for such a large series. I think I addressed all issues raised, except finishing the memleak issues, which I'll continue working on. Stefan diff --git c/object-store.h w/object-store.h index 62763b8412..a6051ccb73 100644 --- c/object-store.h +++ w/object-store.h @@ -60,6 +60,8 @@ struct raw_object_store { #define RAW_OBJECT_STORE_INIT \ { NULL, MRU_INIT, ALTERNATES_INIT, { NULL, 0, 0, 0 }, 0, 0, 0 } +extern void raw_object_store_clear(struct raw_object_store *o); + struct packed_git { struct packed_git *next; struct pack_window *windows; diff --git c/object.c w/object.c index 2fe5fac3ce..f13f9d97f4 100644 --- c/object.c +++ w/object.c @@ -440,3 +440,20 @@ void clear_object_flags(unsigned flags) obj->flags &= ~flags; } } + + +void raw_object_store_clear(struct raw_object_store *o) +{ + /* TODO: free alt_odb_list/tail */ + /* TODO: clear packed_git, packed_git_mru */ +} + +void object_parser_clear(struct object_parser *o) +{ + /* + * TOOD free objects in o->obj_hash. + * + * As objects are allocated in slabs (see alloc.c), we do + * not need to free each object, but each slab instead. + */ +} diff --git c/object.h w/object.h index 900f1b6611..0b42b09322 100644 --- c/object.h +++ w/object.h @@ -43,6 +43,8 @@ extern struct alloc_state the_repository_object_state; &the_repository_object_state, \ 0 } +extern void object_parser_clear(struct object_parser *o); + struct object_list { struct object *item; struct object_list *next; diff --git c/repository.c w/repository.c index 64fb6d8b34..d5ea158b26 100644 --- c/repository.c +++ w/repository.c @@ -141,6 +141,9 @@ static void repo_clear(struct repository *repo) FREE_AND_NULL(repo->worktree); FREE_AND_NULL(repo->submodule_prefix); + raw_object_store_clear(&repo->objects); + object_parser_clear(&repo->parsed_objects); + if (repo->config) { git_configset_clear(repo->config); FREE_AND_NULL(repo->config); diff --git c/submodule.c w/submodule.c index 9bd337ce99..c9634f84ef 100644 --- c/submodule.c +++ w/submodule.c @@ -494,10 +494,7 @@ static int open_submodule(struct repository *out, const char *path) { struct strbuf sb = STRBUF_INIT; - if (submodule_to_gitdir(&sb, path)) - return -1; - - if (repo_init(out, sb.buf, NULL)) { + if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) { strbuf_release(&sb); return -1; } diff --git c/t/t5531-deep-submodule-push.sh w/t/t5531-deep-submodule-push.sh index 8b2aa5a0f4..39cb2c1c34 100755 --- c/t/t5531-deep-submodule-push.sh +++ w/t/t5531-deep-submodule-push.sh @@ -308,22 +308,6 @@ test_expect_success 'submodule entry pointing at a tag is error' ' test_i18ngrep "is a tag, not a commit" err ' -test_expect_success 'replace ref does not interfere with submodule access' ' - test_commit -C work/gar/bage one && - test_commit -C work/gar/bage two && - git -C work/gar/bage reset HEAD^^ && - git -C work/gar/bage replace two one && - test_when_finished "git -C work/gar/bage replace -d two" && - - test_commit -C work/gar/bage three && - git -C work add gar/bage && - git -C work commit -m "advance submodule" && - - git -C work push --recurse-submodules=on-demand ../pub.git master 2>err && - ! grep error err && - ! grep fatal err -' - test_expect_success 'push fails if recurse submodules option passed as yes' ' ( cd work/gar/bage &&