mirror of
https://github.com/git/git.git
synced 2024-11-27 03:53:55 +08:00
submodule: fix latent check_has_commit() bug
When check_has_commit() is called on a missing submodule, initialization
of the struct repository fails, but it attempts to clear the struct
anyway (which is a fatal error). This bug is masked by its only caller,
submodule_has_commits(), first calling add_submodule_odb(). The latter
fails if the submodule does not exist, making submodule_has_commits()
exit early and not invoke check_has_commit().
Fix this bug, and because calling add_submodule_odb() is no longer
necessary as of 13a2f620b2
(submodule: pass repo to
check_has_commit(), 2021-10-08), remove that call too.
This is the last caller of add_submodule_odb(), so remove that
function. (Submodule ODBs are still added as alternates via
add_submodule_odb_by_path().)
Signed-off-by: Glen Choo <chooglen@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
b90d9f7632
commit
5fff35d880
35
submodule.c
35
submodule.c
@ -167,26 +167,6 @@ void stage_updated_gitmodules(struct index_state *istate)
|
||||
|
||||
static struct string_list added_submodule_odb_paths = STRING_LIST_INIT_NODUP;
|
||||
|
||||
/* TODO: remove this function, use repo_submodule_init instead. */
|
||||
int add_submodule_odb(const char *path)
|
||||
{
|
||||
struct strbuf objects_directory = STRBUF_INIT;
|
||||
int ret = 0;
|
||||
|
||||
ret = strbuf_git_path_submodule(&objects_directory, path, "objects/");
|
||||
if (ret)
|
||||
goto done;
|
||||
if (!is_directory(objects_directory.buf)) {
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
string_list_insert(&added_submodule_odb_paths,
|
||||
strbuf_detach(&objects_directory, NULL));
|
||||
done:
|
||||
strbuf_release(&objects_directory);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void add_submodule_odb_by_path(const char *path)
|
||||
{
|
||||
string_list_insert(&added_submodule_odb_paths, xstrdup(path));
|
||||
@ -986,7 +966,8 @@ static int check_has_commit(const struct object_id *oid, void *data)
|
||||
|
||||
if (repo_submodule_init(&subrepo, cb->repo, cb->path, cb->super_oid)) {
|
||||
cb->result = 0;
|
||||
goto cleanup;
|
||||
/* subrepo failed to init, so don't clean it up. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
type = oid_object_info(&subrepo, oid, NULL);
|
||||
@ -1022,18 +1003,6 @@ static int submodule_has_commits(struct repository *r,
|
||||
.super_oid = super_oid
|
||||
};
|
||||
|
||||
/*
|
||||
* Perform a cheap, but incorrect check for the existence of 'commits'.
|
||||
* This is done by adding the submodule's object store to the in-core
|
||||
* object store, and then querying for each commit's existence. If we
|
||||
* do not have the commit object anywhere, there is no chance we have
|
||||
* it in the object store of the correct submodule and have it
|
||||
* reachable from a ref, so we can fail early without spawning rev-list
|
||||
* which is expensive.
|
||||
*/
|
||||
if (add_submodule_odb(path))
|
||||
return 0;
|
||||
|
||||
oid_array_for_each_unique(commits, check_has_commit, &has_commit);
|
||||
|
||||
if (has_commit.result) {
|
||||
|
@ -103,12 +103,11 @@ int submodule_uses_gitfile(const char *path);
|
||||
int bad_to_remove_submodule(const char *path, unsigned flags);
|
||||
|
||||
/*
|
||||
* Call add_submodule_odb() to add the submodule at the given path to a list.
|
||||
* When register_all_submodule_odb_as_alternates() is called, the object stores
|
||||
* of all submodules in that list will be added as alternates in
|
||||
* the_repository.
|
||||
* Call add_submodule_odb_by_path() to add the submodule at the given
|
||||
* path to a list. When register_all_submodule_odb_as_alternates() is
|
||||
* called, the object stores of all submodules in that list will be
|
||||
* added as alternates in the_repository.
|
||||
*/
|
||||
int add_submodule_odb(const char *path);
|
||||
void add_submodule_odb_by_path(const char *path);
|
||||
int register_all_submodule_odb_as_alternates(void);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user