Merge branch 'jk/maint-fetch-submodule-check-fix' into maint
* jk/maint-fetch-submodule-check-fix: fetch: avoid quadratic loop checking for updated submodules
This commit is contained in:
commit
e2d0a2e440
77
submodule.c
77
submodule.c
@ -8,12 +8,17 @@
|
|||||||
#include "diffcore.h"
|
#include "diffcore.h"
|
||||||
#include "refs.h"
|
#include "refs.h"
|
||||||
#include "string-list.h"
|
#include "string-list.h"
|
||||||
|
#include "sha1-array.h"
|
||||||
|
|
||||||
static struct string_list config_name_for_path;
|
static struct string_list config_name_for_path;
|
||||||
static struct string_list config_fetch_recurse_submodules_for_name;
|
static struct string_list config_fetch_recurse_submodules_for_name;
|
||||||
static struct string_list config_ignore_for_name;
|
static struct string_list config_ignore_for_name;
|
||||||
static int config_fetch_recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND;
|
static int config_fetch_recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND;
|
||||||
static struct string_list changed_submodule_paths;
|
static struct string_list changed_submodule_paths;
|
||||||
|
static int initialized_fetch_ref_tips;
|
||||||
|
static struct sha1_array ref_tips_before_fetch;
|
||||||
|
static struct sha1_array ref_tips_after_fetch;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following flag is set if the .gitmodules file is unmerged. We then
|
* The following flag is set if the .gitmodules file is unmerged. We then
|
||||||
* disable recursion for all submodules where .git/config doesn't have a
|
* disable recursion for all submodules where .git/config doesn't have a
|
||||||
@ -474,20 +479,76 @@ static void submodule_collect_changed_cb(struct diff_queue_struct *q,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int add_sha1_to_array(const char *ref, const unsigned char *sha1,
|
||||||
|
int flags, void *data)
|
||||||
|
{
|
||||||
|
sha1_array_append(data, sha1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void check_for_new_submodule_commits(unsigned char new_sha1[20])
|
void check_for_new_submodule_commits(unsigned char new_sha1[20])
|
||||||
|
{
|
||||||
|
if (!initialized_fetch_ref_tips) {
|
||||||
|
for_each_ref(add_sha1_to_array, &ref_tips_before_fetch);
|
||||||
|
initialized_fetch_ref_tips = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sha1_array_append(&ref_tips_after_fetch, new_sha1);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct argv_array {
|
||||||
|
const char **argv;
|
||||||
|
unsigned int argc;
|
||||||
|
unsigned int alloc;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void init_argv(struct argv_array *array)
|
||||||
|
{
|
||||||
|
array->argv = NULL;
|
||||||
|
array->argc = 0;
|
||||||
|
array->alloc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void push_argv(struct argv_array *array, const char *value)
|
||||||
|
{
|
||||||
|
ALLOC_GROW(array->argv, array->argc + 2, array->alloc);
|
||||||
|
array->argv[array->argc++] = xstrdup(value);
|
||||||
|
array->argv[array->argc] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_argv(struct argv_array *array)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < array->argc; i++)
|
||||||
|
free((char **)array->argv[i]);
|
||||||
|
free(array->argv);
|
||||||
|
init_argv(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_sha1_to_argv(const unsigned char sha1[20], void *data)
|
||||||
|
{
|
||||||
|
push_argv(data, sha1_to_hex(sha1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void calculate_changed_submodule_paths(void)
|
||||||
{
|
{
|
||||||
struct rev_info rev;
|
struct rev_info rev;
|
||||||
struct commit *commit;
|
struct commit *commit;
|
||||||
const char *argv[] = {NULL, NULL, "--not", "--all", NULL};
|
struct argv_array argv;
|
||||||
int argc = ARRAY_SIZE(argv) - 1;
|
|
||||||
|
|
||||||
/* No need to check if there are no submodules configured */
|
/* No need to check if there are no submodules configured */
|
||||||
if (!config_name_for_path.nr)
|
if (!config_name_for_path.nr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
init_revisions(&rev, NULL);
|
init_revisions(&rev, NULL);
|
||||||
argv[1] = xstrdup(sha1_to_hex(new_sha1));
|
init_argv(&argv);
|
||||||
setup_revisions(argc, argv, &rev, NULL);
|
push_argv(&argv, "--"); /* argv[0] program name */
|
||||||
|
sha1_array_for_each_unique(&ref_tips_after_fetch,
|
||||||
|
add_sha1_to_argv, &argv);
|
||||||
|
push_argv(&argv, "--not");
|
||||||
|
sha1_array_for_each_unique(&ref_tips_before_fetch,
|
||||||
|
add_sha1_to_argv, &argv);
|
||||||
|
setup_revisions(argv.argc, argv.argv, &rev, NULL);
|
||||||
if (prepare_revision_walk(&rev))
|
if (prepare_revision_walk(&rev))
|
||||||
die("revision walk setup failed");
|
die("revision walk setup failed");
|
||||||
|
|
||||||
@ -511,7 +572,11 @@ void check_for_new_submodule_commits(unsigned char new_sha1[20])
|
|||||||
parent = parent->next;
|
parent = parent->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free((char *)argv[1]);
|
|
||||||
|
clear_argv(&argv);
|
||||||
|
sha1_array_clear(&ref_tips_before_fetch);
|
||||||
|
sha1_array_clear(&ref_tips_after_fetch);
|
||||||
|
initialized_fetch_ref_tips = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fetch_populated_submodules(int num_options, const char **options,
|
int fetch_populated_submodules(int num_options, const char **options,
|
||||||
@ -545,6 +610,8 @@ int fetch_populated_submodules(int num_options, const char **options,
|
|||||||
cp.git_cmd = 1;
|
cp.git_cmd = 1;
|
||||||
cp.no_stdin = 1;
|
cp.no_stdin = 1;
|
||||||
|
|
||||||
|
calculate_changed_submodule_paths();
|
||||||
|
|
||||||
for (i = 0; i < active_nr; i++) {
|
for (i = 0; i < active_nr; i++) {
|
||||||
struct strbuf submodule_path = STRBUF_INIT;
|
struct strbuf submodule_path = STRBUF_INIT;
|
||||||
struct strbuf submodule_git_dir = STRBUF_INIT;
|
struct strbuf submodule_git_dir = STRBUF_INIT;
|
||||||
|
Loading…
Reference in New Issue
Block a user