From e7fed18a89fae97655687e19f13cd802d8d70845 Mon Sep 17 00:00:00 2001 From: Johan Herland Date: Thu, 20 Aug 2009 01:07:43 +0200 Subject: [PATCH] git clone: Add --recursive to automatically checkout (nested) submodules Many projects using submodules expect all submodules to be checked out in order to build/work correctly. A common command sequence for developers on such projects is: git clone url/to/project cd project git submodule update --init (--recursive) This patch introduces the --recursive option to git-clone. The new option causes git-clone to recursively clone and checkout all submodules of the cloned project. Hence, the above command sequence can be reduced to: git clone --recursive url/to/project --recursive is ignored if no checkout is done by the git-clone. The patch also includes documentation and a selftest. Signed-off-by: Johan Herland Signed-off-by: Junio C Hamano --- Documentation/git-clone.txt | 10 +++++++++- builtin-clone.c | 11 ++++++++++- t/t7407-submodule-foreach.sh | 12 ++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index b14de6c407..5a685ceec9 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -12,7 +12,7 @@ SYNOPSIS 'git clone' [--template=] [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror] [-o ] [-u ] [--reference ] - [--depth ] [--] [] + [--depth ] [--recursive] [--] [] DESCRIPTION ----------- @@ -139,6 +139,14 @@ then the cloned repository will become corrupt. with a long history, and would want to send in fixes as patches. +--recursive:: + After the clone is created, initialize all submodules within, + using their default settings. This is equivalent to running + 'git submodule update --init --recursive' immediately after + the clone is finished. This option is ignored if the cloned + repository does not have a worktree/checkout (i.e. if any of + `--no-checkout`/`-n`, `--bare`, or `--mirror` is given) + :: The (possibly remote) repository to clone from. See the <> section below for more information on specifying diff --git a/builtin-clone.c b/builtin-clone.c index 32dea74d78..0d2b4a8200 100644 --- a/builtin-clone.c +++ b/builtin-clone.c @@ -38,7 +38,7 @@ static const char * const builtin_clone_usage[] = { }; static int option_quiet, option_no_checkout, option_bare, option_mirror; -static int option_local, option_no_hardlinks, option_shared; +static int option_local, option_no_hardlinks, option_shared, option_recursive; static char *option_template, *option_reference, *option_depth; static char *option_origin = NULL; static char *option_upload_pack = "git-upload-pack"; @@ -59,6 +59,8 @@ static struct option builtin_clone_options[] = { "don't use local hardlinks, always copy"), OPT_BOOLEAN('s', "shared", &option_shared, "setup as shared repository"), + OPT_BOOLEAN(0, "recursive", &option_recursive, + "setup as shared repository"), OPT_STRING(0, "template", &option_template, "path", "path the template repository"), OPT_STRING(0, "reference", &option_reference, "repo", @@ -73,6 +75,10 @@ static struct option builtin_clone_options[] = { OPT_END() }; +static const char *argv_submodule[] = { + "submodule", "update", "--init", "--recursive", NULL +}; + static char *get_repo_path(const char *repo, int *is_bundle) { static char *suffix[] = { "/.git", ".git", "" }; @@ -608,6 +614,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix) err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1), sha1_to_hex(remote_head->old_sha1), "1", NULL); + + if (!err && option_recursive) + err = run_command_v_opt(argv_submodule, RUN_GIT_CMD); } strbuf_release(&reflog_msg); diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh index 519db49ea6..2a527750ce 100755 --- a/t/t7407-submodule-foreach.sh +++ b/t/t7407-submodule-foreach.sh @@ -222,4 +222,16 @@ test_expect_success 'test "status --recursive"' ' test_cmp expect actual ' +test_expect_success 'use "git clone --recursive" to checkout all submodules' ' + git clone --recursive super clone4 && + test -d clone4/.git && + test -d clone4/sub1/.git && + test -d clone4/sub2/.git && + test -d clone4/sub3/.git && + test -d clone4/nested1/.git && + test -d clone4/nested1/nested2/.git && + test -d clone4/nested1/nested2/nested3/.git && + test -d clone4/nested1/nested2/nested3/submodule/.git +' + test_done -- 2.11.4.GIT