In later patches we introduce the --recurse-submodule flag for commands that modify the working directory, e.g. git-checkout. It is potentially expensive to check if a submodule needs an update, because a common theme to interact with submodules is to spawn a child process for each interaction. So let's introduce a function that pre checks if a submodule needs to be checked for an update. I am not particular happy with the name `submodule_is_interesting`, in internal iterations I had `submodule_requires_check_for_update` and `submodule_needs_update`, but I was even less happy with those names. Maybe `submodule_interesting_for_update`? Generally this is to answer "Am I allowed to touch the submodule at all?" or: "Does the user expect me to touch it?" which includes all of creation/deletion/update. This patch is based off a prior attempt by Jens Lehmann to add submodules to checkout. Signed-off-by: Stefan Beller <sbeller@xxxxxxxxxx> --- submodule.c | 37 +++++++++++++++++++++++++++++++++++++ submodule.h | 8 ++++++++ 2 files changed, 45 insertions(+) diff --git a/submodule.c b/submodule.c index 38b0573..d34b721 100644 --- a/submodule.c +++ b/submodule.c @@ -500,6 +500,43 @@ void set_config_update_recurse_submodules(int value) config_update_recurse_submodules = value; } +int submodules_interesting_for_update(void) +{ + /* + * Update can't be "none", "merge" or "rebase", + * treat any value as OFF, except an explicit ON. + */ + return config_update_recurse_submodules == RECURSE_SUBMODULES_ON; +} + +int submodule_is_interesting(const char *path, const unsigned char *sha1) +{ + /* + * If we cannot load a submodule config, we cannot get the name + * of the submodule, so we'd need to follow the gitlink file + */ + const struct submodule *sub; + + if (!submodules_interesting_for_update()) + return 0; + + sub = submodule_from_path(sha1, path); + if (!sub) + return 0; + + switch (sub->update_strategy.type) { + case SM_UPDATE_UNSPECIFIED: + case SM_UPDATE_CHECKOUT: + return 1; + case SM_UPDATE_REBASE: + case SM_UPDATE_MERGE: + case SM_UPDATE_NONE: + case SM_UPDATE_COMMAND: + return 0; + } + return 0; +} + static int has_remote(const char *refname, const struct object_id *oid, int flags, void *cb_data) { diff --git a/submodule.h b/submodule.h index 185ad18..3df6881 100644 --- a/submodule.h +++ b/submodule.h @@ -57,6 +57,14 @@ extern void show_submodule_inline_diff(FILE *f, const char *path, const struct diff_options *opt); extern void set_config_fetch_recurse_submodules(int value); extern void set_config_update_recurse_submodules(int value); +/** + * When updating the working tree, do we need to check if the submodule needs + * updating. We do not require a check if we are already sure that the + * submodule doesn't need updating, e.g. when we are not interested in submodules + * or the submodule is marked uninteresting by being not initialized. + */ +extern int submodule_is_interesting(const char *path, const unsigned char *sha1); +extern int submodules_interesting_for_update(void); extern void check_for_new_submodule_commits(unsigned char new_sha1[20]); extern int fetch_populated_submodules(const struct argv_array *options, const char *prefix, int command_line_option, -- 2.10.1.469.g00a8914