Skip to content

Commit e7fed18

Browse files
jherlandgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e3ae4a8 commit e7fed18

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

Documentation/git-clone.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ SYNOPSIS
1212
'git clone' [--template=<template_directory>]
1313
[-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
1414
[-o <name>] [-u <upload-pack>] [--reference <repository>]
15-
[--depth <depth>] [--] <repository> [<directory>]
15+
[--depth <depth>] [--recursive] [--] <repository> [<directory>]
1616

1717
DESCRIPTION
1818
-----------
@@ -139,6 +139,14 @@ then the cloned repository will become corrupt.
139139
with a long history, and would want to send in fixes
140140
as patches.
141141

142+
--recursive::
143+
After the clone is created, initialize all submodules within,
144+
using their default settings. This is equivalent to running
145+
'git submodule update --init --recursive' immediately after
146+
the clone is finished. This option is ignored if the cloned
147+
repository does not have a worktree/checkout (i.e. if any of
148+
`--no-checkout`/`-n`, `--bare`, or `--mirror` is given)
149+
142150
<repository>::
143151
The (possibly remote) repository to clone from. See the
144152
<<URLS,URLS>> section below for more information on specifying

builtin-clone.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ static const char * const builtin_clone_usage[] = {
3838
};
3939

4040
static int option_quiet, option_no_checkout, option_bare, option_mirror;
41-
static int option_local, option_no_hardlinks, option_shared;
41+
static int option_local, option_no_hardlinks, option_shared, option_recursive;
4242
static char *option_template, *option_reference, *option_depth;
4343
static char *option_origin = NULL;
4444
static char *option_upload_pack = "git-upload-pack";
@@ -59,6 +59,8 @@ static struct option builtin_clone_options[] = {
5959
"don't use local hardlinks, always copy"),
6060
OPT_BOOLEAN('s', "shared", &option_shared,
6161
"setup as shared repository"),
62+
OPT_BOOLEAN(0, "recursive", &option_recursive,
63+
"setup as shared repository"),
6264
OPT_STRING(0, "template", &option_template, "path",
6365
"path the template repository"),
6466
OPT_STRING(0, "reference", &option_reference, "repo",
@@ -73,6 +75,10 @@ static struct option builtin_clone_options[] = {
7375
OPT_END()
7476
};
7577

78+
static const char *argv_submodule[] = {
79+
"submodule", "update", "--init", "--recursive", NULL
80+
};
81+
7682
static char *get_repo_path(const char *repo, int *is_bundle)
7783
{
7884
static char *suffix[] = { "/.git", ".git", "" };
@@ -608,6 +614,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
608614

609615
err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1),
610616
sha1_to_hex(remote_head->old_sha1), "1", NULL);
617+
618+
if (!err && option_recursive)
619+
err = run_command_v_opt(argv_submodule, RUN_GIT_CMD);
611620
}
612621

613622
strbuf_release(&reflog_msg);

t/t7407-submodule-foreach.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,16 @@ test_expect_success 'test "status --recursive"' '
222222
test_cmp expect actual
223223
'
224224

225+
test_expect_success 'use "git clone --recursive" to checkout all submodules' '
226+
git clone --recursive super clone4 &&
227+
test -d clone4/.git &&
228+
test -d clone4/sub1/.git &&
229+
test -d clone4/sub2/.git &&
230+
test -d clone4/sub3/.git &&
231+
test -d clone4/nested1/.git &&
232+
test -d clone4/nested1/nested2/.git &&
233+
test -d clone4/nested1/nested2/nested3/.git &&
234+
test -d clone4/nested1/nested2/nested3/submodule/.git
235+
'
236+
225237
test_done

0 commit comments

Comments
 (0)