To achieve this, the new member "ignore_submodules" has been added to the bitfield in "struct checkout". All users of "struct checkout" are setting this flag to 1 for backward compatibility for now. Also the new function checkout_submodule() has been added and is called by checkout_entry() when "ignore_submodules" is false (which will be the default behavior later). Signed-off-by: Jens Lehmann <Jens.Lehmann@xxxxxx> --- builtin/apply.c | 1 + builtin/checkout-index.c | 1 + builtin/checkout.c | 1 + cache.h | 3 ++- entry.c | 9 ++++++--- submodule.c | 32 ++++++++++++++++++++++++++++++++ submodule.h | 1 + unpack-trees.c | 1 + 8 files changed, 45 insertions(+), 4 deletions(-) diff --git a/builtin/apply.c b/builtin/apply.c index ec755ac..a7788a9 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -2827,6 +2827,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s costate.quiet = 0; costate.not_new = 0; costate.refresh_cache = 1; + costate.ignore_submodules = 1; if (checkout_entry(*ce, &costate, NULL) || lstat(old_name, st)) return -1; diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c index a7a5ee1..c35bad3 100644 --- a/builtin/checkout-index.c +++ b/builtin/checkout-index.c @@ -254,6 +254,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix) state.force = force; state.quiet = quiet; state.not_new = not_new; + state.ignore_submodules = 1; if (state.base_dir_len || to_tempfile) { /* when --prefix is specified we do not diff --git a/builtin/checkout.c b/builtin/checkout.c index c382521..ee198ae 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -248,6 +248,7 @@ static int checkout_paths(struct tree *source_tree, const char **pathspec, memset(&state, 0, sizeof(state)); state.force = 1; state.refresh_cache = 1; + state.ignore_submodules = 1; for (pos = 0; pos < active_nr; pos++) { struct cache_entry *ce = active_cache[pos]; if (match_pathspec(pathspec, ce->name, ce_namelen(ce), 0, NULL)) { diff --git a/cache.h b/cache.h index 303c107..996fa69 100644 --- a/cache.h +++ b/cache.h @@ -802,7 +802,8 @@ struct checkout { unsigned force:1, quiet:1, not_new:1, - refresh_cache:1; + refresh_cache:1, + ignore_submodules:1; }; extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath); diff --git a/entry.c b/entry.c index 004182c..15dec09 100644 --- a/entry.c +++ b/entry.c @@ -1,6 +1,7 @@ #include "cache.h" #include "blob.h" #include "dir.h" +#include "submodule.h" static void create_directories(const char *path, int path_len, const struct checkout *state) @@ -222,9 +223,11 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t * just do the right thing) */ if (S_ISDIR(st.st_mode)) { - /* If it is a gitlink, leave it alone! */ - if (S_ISGITLINK(ce->ce_mode)) - return 0; + if (S_ISGITLINK(ce->ce_mode)) { + if (state->ignore_submodules) + return 0; + return checkout_submodule(ce->name, ce->sha1, state->force); + } if (!state->force) return error("%s is a directory", path); remove_subtree(path); diff --git a/submodule.c b/submodule.c index b3b8bc1..59029b2 100644 --- a/submodule.c +++ b/submodule.c @@ -206,3 +206,35 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) strbuf_release(&buf); return dirty_submodule; } + +int checkout_submodule(const char *path, const unsigned char sha1[20], int force) +{ + struct strbuf buf = STRBUF_INIT; + struct child_process cp; + const char *hex_sha1 = sha1_to_hex(sha1); + const char *argv[] = { + "checkout", + force ? "-qf" : "-q", + hex_sha1, + NULL, + }; + + strbuf_addf(&buf, "%s/.git/", path); + if (!is_directory(buf.buf)) { + strbuf_release(&buf); + /* The submodule is not populated, so we can't check it out */ + return 0; + } + + memset(&cp, 0, sizeof(cp)); + cp.argv = argv; + cp.env = local_repo_env; + cp.git_cmd = 1; + cp.no_stdin = 1; + cp.out = -1; + cp.dir = path; /* GIT_WORK_TREE doesn't work for git checkout */ + if (run_command(&cp)) + return error("Could not checkout submodule %s", path); + + return 0; +} diff --git a/submodule.h b/submodule.h index dbda270..fc6909e 100644 --- a/submodule.h +++ b/submodule.h @@ -6,5 +6,6 @@ void show_submodule_summary(FILE *f, const char *path, unsigned dirty_submodule, const char *del, const char *add, const char *reset); unsigned is_submodule_modified(const char *path, int ignore_untracked); +int checkout_submodule(const char *path, const unsigned char sha1[20], int force); #endif diff --git a/unpack-trees.c b/unpack-trees.c index c29a9e0..151b422 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -711,6 +711,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options state.force = 1; state.quiet = 1; state.refresh_cache = 1; + state.ignore_submodules = 1; memset(&el, 0, sizeof(el)); if (!core_apply_sparse_checkout || !o->update) -- 1.7.1.rc0.248.g09203 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html