From: Stefan Beller <sbeller@google.com>
To: bmwill@google.com, David.Turner@twosigma.com
Cc: git@vger.kernel.org, sandals@crustytoothpaste.net,
hvoigt@hvoigt.net, gitster@pobox.com,
Stefan Beller <sbeller@google.com>
Subject: [RFC PATCHv2 09/17] update submodules: add scheduling to update submodules
Date: Fri, 2 Dec 2016 16:30:14 -0800 [thread overview]
Message-ID: <20161203003022.29797-10-sbeller@google.com> (raw)
In-Reply-To: <20161203003022.29797-1-sbeller@google.com>
The walker of a tree is only expected to call `schedule_submodule_for_update`
and once done, to run `update_submodules`. This avoids directory/file
conflicts and later we can parallelize all submodule actions if needed.
Signed-off-by: Stefan Beller <sbeller@google.com>
---
submodule.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
submodule.h | 5 +++
2 files changed, 137 insertions(+)
diff --git a/submodule.c b/submodule.c
index 7bb64d6c69..02c28ef56b 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1348,3 +1348,135 @@ int parallel_submodules(void)
{
return parallel_jobs;
}
+
+static struct scheduled_submodules_update_type {
+ const char *path;
+ const struct object_id *oid;
+ /*
+ * Do we need to perform a complete checkout or just incremental
+ * update?
+ */
+ unsigned is_new:1;
+} *scheduled_submodules;
+#define SCHEDULED_SUBMODULES_INIT {NULL, NULL, 0}
+
+static int scheduled_submodules_nr, scheduled_submodules_alloc;
+
+void schedule_submodule_for_update(const struct cache_entry *ce, int is_new)
+{
+ struct scheduled_submodules_update_type *ssu;
+ ALLOC_GROW(scheduled_submodules,
+ scheduled_submodules_nr + 1,
+ scheduled_submodules_alloc);
+ ssu = &scheduled_submodules[scheduled_submodules_nr++];
+ ssu->path = ce->name;
+ ssu->oid = &ce->oid;
+ ssu->is_new = !!is_new;
+}
+
+static int update_submodule(const char *path, const struct object_id *oid,
+ int force, int is_new)
+{
+ const char *git_dir;
+ struct child_process cp = CHILD_PROCESS_INIT;
+ const struct submodule *sub = submodule_from_path(null_sha1, path);
+
+ if (!sub || !sub->name)
+ return -1;
+
+ git_dir = resolve_gitdir(git_common_path("modules/%s", sub->name));
+
+ if (!git_dir)
+ return -1;
+
+ if (is_new)
+ connect_work_tree_and_git_dir(path, git_dir);
+
+ /* update index via `read-tree --reset sha1` */
+ argv_array_pushl(&cp.args, "read-tree",
+ force ? "--reset" : "-m",
+ "-u", sha1_to_hex(oid->hash), NULL);
+ prepare_submodule_repo_env(&cp.env_array);
+ cp.git_cmd = 1;
+ cp.no_stdin = 1;
+ cp.dir = path;
+ if (run_command(&cp)) {
+ warning(_("reading the index in submodule '%s' failed"), path);
+ child_process_clear(&cp);
+ return -1;
+ }
+
+ /* write index to working dir */
+ child_process_clear(&cp);
+ child_process_init(&cp);
+ argv_array_pushl(&cp.args, "checkout-index", "-a", NULL);
+ cp.git_cmd = 1;
+ cp.no_stdin = 1;
+ cp.dir = path;
+ if (force)
+ argv_array_push(&cp.args, "-f");
+
+ if (run_command(&cp)) {
+ warning(_("populating the working directory in submodule '%s' failed"), path);
+ child_process_clear(&cp);
+ return -1;
+ }
+
+ /* get the HEAD right */
+ child_process_clear(&cp);
+ child_process_init(&cp);
+ argv_array_pushl(&cp.args, "checkout", "--recurse-submodules", NULL);
+ cp.git_cmd = 1;
+ cp.no_stdin = 1;
+ cp.dir = path;
+ if (force)
+ argv_array_push(&cp.args, "-f");
+ argv_array_push(&cp.args, sha1_to_hex(oid->hash));
+
+ if (run_command(&cp)) {
+ warning(_("setting the HEAD in submodule '%s' failed"), path);
+ child_process_clear(&cp);
+ return -1;
+ }
+
+ child_process_clear(&cp);
+ return 0;
+}
+
+int update_submodules(int force)
+{
+ int i;
+ gitmodules_config();
+
+ /*
+ * NEEDSWORK: As submodule updates can potentially take some
+ * time each and they do not overlap (i.e. no d/f conflicts;
+ * this can be parallelized using the run_commands.h API.
+ */
+ for (i = 0; i < scheduled_submodules_nr; i++) {
+ struct submodule *sub;
+ struct scheduled_submodules_update_type *ssu =
+ &scheduled_submodules[i];
+
+ if (!submodule_is_interesting(ssu->path))
+ continue;
+
+ sub = submodule_from_path(null_sha1, ssu->path);
+
+ switch (sub->update_strategy) {
+ case SM_UPDATE_UNSPECIFIED: /* fall thru */
+ case SM_UPDATE_CHECKOUT:
+ update_submodule(ssu->path, ssu->oid,
+ force, ssu->is_new);
+ break;
+ case SM_UPDATE_REBASE:
+ case SM_UPDATE_MERGE:
+ case SM_UPDATE_NONE:
+ case SM_UPDATE_COMMAND:
+ warning("update strategy for submodule '%s' not supported", ssu->path);
+ }
+ }
+
+ scheduled_submodules_nr = 0;
+ return 0;
+}
diff --git a/submodule.h b/submodule.h
index d8bb1d4baf..74df8b93d5 100644
--- a/submodule.h
+++ b/submodule.h
@@ -90,4 +90,9 @@ extern int parallel_submodules(void);
* retaining any config in the environment.
*/
extern void prepare_submodule_repo_env(struct argv_array *out);
+
+extern void schedule_submodule_for_update(const struct cache_entry *ce,
+ int new);
+extern int update_submodules(int force);
+
#endif
--
2.11.0.rc2.28.g2673dad
next prev parent reply other threads:[~2016-12-03 0:31 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-03 0:30 [RFC PATCHv2 00/17] Checkout aware of Submodules! Stefan Beller
2016-12-03 0:30 ` [RFC PATCHv2 01/17] submodule.h: add extern keyword to functions Stefan Beller
2016-12-03 0:30 ` [RFC PATCHv2 02/17] submodule: modernize ok_to_remove_submodule to use argv_array Stefan Beller
2016-12-03 0:30 ` [RFC PATCHv2 03/17] update submodules: move up prepare_submodule_repo_env Stefan Beller
2016-12-03 0:30 ` [RFC PATCHv2 04/17] update submodules: add is_submodule_populated Stefan Beller
2016-12-03 0:30 ` [RFC PATCHv2 05/17] update submodules: add submodule config parsing Stefan Beller
2016-12-03 0:30 ` [RFC PATCHv2 06/17] update submodules: add a config option to determine if submodules are updated Stefan Beller
2016-12-03 0:30 ` [RFC PATCHv2 07/17] update submodules: introduce submodule_is_interesting Stefan Beller
2016-12-03 0:30 ` [RFC PATCHv2 08/17] update submodules: add depopulate_submodule Stefan Beller
2016-12-05 23:37 ` David Turner
2016-12-06 0:18 ` Stefan Beller
2016-12-03 0:30 ` Stefan Beller [this message]
2016-12-05 23:37 ` [RFC PATCHv2 09/17] update submodules: add scheduling to update submodules David Turner
2016-12-05 23:54 ` Stefan Beller
2016-12-03 0:30 ` [RFC PATCHv2 10/17] update submodules: is_submodule_checkout_safe Stefan Beller
2016-12-03 0:30 ` [RFC PATCHv2 11/17] unpack-trees: teach verify_clean_submodule to inspect submodules Stefan Beller
2016-12-03 0:30 ` [RFC PATCHv2 12/17] unpack-trees: remove submodule contents if interesting Stefan Beller
2016-12-03 0:30 ` [RFC PATCHv2 13/17] entry: write_entry to write populate submodules Stefan Beller
2016-12-03 0:30 ` [RFC PATCHv2 14/17] submodule: teach unpack_trees() to update submodules Stefan Beller
2016-12-05 23:37 ` David Turner
2016-12-03 0:30 ` [RFC PATCHv2 15/17] checkout: recurse into submodules if asked to Stefan Beller
2016-12-05 19:25 ` Brandon Williams
2016-12-05 19:30 ` Stefan Beller
2016-12-05 19:31 ` Brandon Williams
2016-12-05 23:36 ` David Turner
2016-12-03 0:30 ` [RFC PATCHv2 16/17] completion: add '--recurse-submodules' to checkout Stefan Beller
2016-12-03 0:30 ` [RFC PATCHv2 17/17] checkout: add config option to recurse into submodules by default Stefan Beller
2016-12-05 19:29 ` Brandon Williams
2016-12-05 22:23 ` Stefan Beller
2016-12-05 22:26 ` Brandon Williams
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=20161203003022.29797-10-sbeller@google.com \
--to=sbeller@google.com \
--cc=David.Turner@twosigma.com \
--cc=bmwill@google.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=hvoigt@hvoigt.net \
--cc=sandals@crustytoothpaste.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).