From: Stefan Beller <sbeller@google.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, hvoigt@hvoigt.net, Jens.Lehmann@web.de,
Stefan Beller <sbeller@google.com>
Subject: [RFC PATCH 4/4] submodule: add infrastructure to fetch submodules in parallel
Date: Thu, 6 Aug 2015 10:35:24 -0700 [thread overview]
Message-ID: <1438882524-21215-5-git-send-email-sbeller@google.com> (raw)
In-Reply-To: <1438882524-21215-1-git-send-email-sbeller@google.com>
This makes use of the new workdispatcher to fetch a number
of submodules at the same time.
Still todo: sort the output of the fetch commands. I am unsure
if this should be hooked into the workdispatcher as the problem
of sorted output will appear likely again, so a general solution
would not hurt.
Signed-off-by: Stefan Beller <sbeller@google.com>
---
builtin/fetch.c | 3 ++-
submodule.c | 74 ++++++++++++++++++++++++++++++++++++++++++++-------------
submodule.h | 2 +-
3 files changed, 60 insertions(+), 19 deletions(-)
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 8d5b2db..9053e8b 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -1207,7 +1207,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
result = fetch_populated_submodules(&options,
submodule_prefix,
recurse_submodules,
- verbosity < 0);
+ verbosity < 0,
+ 1);
argv_array_clear(&options);
}
diff --git a/submodule.c b/submodule.c
index 872967f..0b2842b 100644
--- a/submodule.c
+++ b/submodule.c
@@ -11,6 +11,7 @@
#include "sha1-array.h"
#include "argv-array.h"
#include "blob.h"
+#include "workdispatcher.h"
static struct string_list config_name_for_path;
static struct string_list config_fetch_recurse_submodules_for_name;
@@ -696,13 +697,49 @@ const char* submodule_name_for_path(const char* path)
return NULL;
}
+struct submodule_parallel_fetch {
+ struct child_process cp;
+ struct argv_array argv;
+ struct strbuf sb;
+ int quiet;
+};
+
+void submodule_parallel_fetch_init(struct submodule_parallel_fetch *spf)
+{
+ child_process_init(&spf->cp);
+ argv_array_init(&spf->argv);
+ strbuf_init(&spf->sb, 0);
+ spf->quiet = 0;
+}
+
+void *run_command_and_cleanup(void *arg)
+{
+ struct submodule_parallel_fetch *spf = arg;
+ void *ret = NULL;
+
+ if (!spf->quiet)
+ puts(spf->sb.buf);
+
+ spf->cp.argv = spf->argv.argv;
+
+ if (run_command(&spf->cp))
+ ret = (void *)1;
+
+ strbuf_release(&spf->cp);
+ argv_array_clear(spf->argv);
+ free(spf);
+ return ret;
+}
+
int fetch_populated_submodules(const struct argv_array *options,
const char *prefix, int command_line_option,
- int quiet)
+ int quiet, int max_parallel_jobs)
{
int i, result = 0;
- struct child_process cp = CHILD_PROCESS_INIT;
+ struct workdispatcher *wd;
+ struct return_values *rv;
struct argv_array argv = ARGV_ARRAY_INIT;
+ struct submodule_parallel_fetch *spf;
const char *name_for_path;
const char *work_tree = get_git_work_tree();
if (!work_tree)
@@ -717,12 +754,9 @@ int fetch_populated_submodules(const struct argv_array *options,
argv_array_push(&argv, "--recurse-submodules-default");
/* default value, "--submodule-prefix" and its value are added later */
- cp.env = local_repo_env;
- cp.git_cmd = 1;
- cp.no_stdin = 1;
-
calculate_changed_submodule_paths();
+ wd = create_workdispatcher(&run_command_and_cleanup, max_parallel_jobs);
for (i = 0; i < active_nr; i++) {
struct strbuf submodule_path = STRBUF_INIT;
struct strbuf submodule_git_dir = STRBUF_INIT;
@@ -771,24 +805,30 @@ int fetch_populated_submodules(const struct argv_array *options,
if (!git_dir)
git_dir = submodule_git_dir.buf;
if (is_directory(git_dir)) {
+ spf = xmalloc(sizeof(*spf));
+ submodule_parallel_fetch_init(spf);
+ spf->cp.env = local_repo_env;
+ spf->cp.git_cmd = 1;
+ spf->cp.no_stdin = 1;
+ spf->cp.dir = strbuf_detach(&submodule_path, NULL);
+ spf->quiet = quiet;
if (!quiet)
- printf("Fetching submodule %s%s\n", prefix, ce->name);
- cp.dir = submodule_path.buf;
- argv_array_push(&argv, default_argv);
- argv_array_push(&argv, "--submodule-prefix");
- argv_array_push(&argv, submodule_prefix.buf);
- cp.argv = argv.argv;
- if (run_command(&cp))
- result = 1;
- argv_array_pop(&argv);
- argv_array_pop(&argv);
- argv_array_pop(&argv);
+ strbuf_addf(&spf->sb, "Fetching submodule %s%s", prefix, ce->name);
+ argv_array_copy(&argv, &spf->argv);
+ argv_array_push(&spf->argv, default_argv);
+ argv_array_push(&spf->argv, "--submodule-prefix");
+ argv_array_push(&spf->argv, submodule_prefix.buf);
+ add_task(wd, spf);
}
strbuf_release(&submodule_path);
strbuf_release(&submodule_git_dir);
strbuf_release(&submodule_prefix);
}
argv_array_clear(&argv);
+ rv = wait_workdispatcher(wd);
+ for (i = 0; i < rv->count; i++)
+ if (rv->ret[i])
+ result = 1;
out:
string_list_clear(&changed_submodule_paths, 1);
return result;
diff --git a/submodule.h b/submodule.h
index e3dd854..51195ea 100644
--- a/submodule.h
+++ b/submodule.h
@@ -31,7 +31,7 @@ void set_config_fetch_recurse_submodules(int value);
void check_for_new_submodule_commits(unsigned char new_sha1[20]);
int fetch_populated_submodules(const struct argv_array *options,
const char *prefix, int command_line_option,
- int quiet);
+ int quiet, int max_parallel_jobs);
unsigned is_submodule_modified(const char *path, int ignore_untracked);
int submodule_uses_gitfile(const char *path);
int ok_to_remove_submodule(const char *path);
--
2.5.0.239.g9728e1d.dirty
next prev parent reply other threads:[~2015-08-06 17:37 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-06 17:35 [RFC/PATCH 0/4] parallel fetch for submodules Stefan Beller
2015-08-06 17:35 ` [PATCH 1/4] submodule: implement `module_name` as a builtin helper Stefan Beller
2015-08-06 19:49 ` Jens Lehmann
2015-08-06 19:54 ` Jens Lehmann
2015-08-06 17:35 ` [RFC PATCH 2/4] Add a workdispatcher to get work done in parallel Stefan Beller
2015-08-06 17:35 ` [PATCH 3/4] argv_array: add argv_array_copy Stefan Beller
2015-08-06 18:18 ` Eric Sunshine
2015-08-06 18:52 ` Jeff King
2015-08-06 17:35 ` Stefan Beller [this message]
2015-08-06 20:08 ` [RFC/PATCH 0/4] parallel fetch for submodules Jens Lehmann
2015-08-06 20:44 ` Stefan Beller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1438882524-21215-5-git-send-email-sbeller@google.com \
--to=sbeller@google.com \
--cc=Jens.Lehmann@web.de \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=hvoigt@hvoigt.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).