Merge branch 'sb/clone-shallow-passthru'
authorJunio C Hamano <gitster@pobox.com>
Fri, 6 May 2016 21:45:43 +0000 (14:45 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 6 May 2016 21:45:43 +0000 (14:45 -0700)
"git clone" learned "--shallow-submodules" option.

* sb/clone-shallow-passthru:
clone: add `--shallow-submodules` flag

Documentation/git-clone.txt
builtin/clone.c
t/t5614-clone-submodules.sh [new file with mode: 0755]
index 45d74be29705bae9ecd3028f4dff5755638741f7..1b15cd7b16620e588d21e1c69a01e2e5d880729e 100644 (file)
@@ -14,8 +14,8 @@ SYNOPSIS
          [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
          [--dissociate] [--separate-git-dir <git dir>]
          [--depth <depth>] [--[no-]single-branch]
-         [--recursive | --recurse-submodules] [--jobs <n>] [--] <repository>
-         [<directory>]
+         [--recursive | --recurse-submodules] [--[no-]shallow-submodules]
+         [--jobs <n>] [--] <repository> [<directory>]
 
 DESCRIPTION
 -----------
@@ -191,7 +191,9 @@ objects from the source repository into a pack in the cloned repository.
        Create a 'shallow' clone with a history truncated to the
        specified number of commits. Implies `--single-branch` unless
        `--no-single-branch` is given to fetch the histories near the
-       tips of all branches.
+       tips of all branches. This implies `--shallow-submodules`. If
+       you want to have a shallow superproject clone, but full submodules,
+       also pass `--no-shallow-submodules`.
 
 --[no-]single-branch::
        Clone only the history leading to the tip of a single branch,
@@ -212,6 +214,9 @@ objects from the source repository into a pack in the cloned repository.
        repository does not have a worktree/checkout (i.e. if any of
        `--no-checkout`/`-n`, `--bare`, or `--mirror` is given)
 
+--[no-]shallow-submodules::
+       All submodules which are cloned will be shallow with a depth of 1.
+
 --separate-git-dir=<git dir>::
        Instead of placing the cloned repository where it is supposed
        to be, place the cloned repository at the specified directory,
index 6576ecf34309db4135c7a41ad6d0ef70e4a21f24..5f867e67d8066fe70fdd67c3d8e2853ea6c3eaa1 100644 (file)
@@ -40,6 +40,7 @@ static const char * const builtin_clone_usage[] = {
 
 static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1;
 static int option_local = -1, option_no_hardlinks, option_shared, option_recursive;
+static int option_shallow_submodules = -1;
 static char *option_template, *option_depth;
 static char *option_origin = NULL;
 static char *option_branch = NULL;
@@ -92,6 +93,8 @@ static struct option builtin_clone_options[] = {
                    N_("create a shallow clone of that depth")),
        OPT_BOOL(0, "single-branch", &option_single_branch,
                    N_("clone only one branch, HEAD or --branch")),
+       OPT_BOOL(0, "shallow-submodules", &option_shallow_submodules,
+                   N_("any cloned submodules will be shallow")),
        OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
                   N_("separate git dir from working tree")),
        OPT_STRING_LIST('c', "config", &option_config, N_("key=value"),
@@ -735,6 +738,10 @@ static int checkout(void)
                struct argv_array args = ARGV_ARRAY_INIT;
                argv_array_pushl(&args, "submodule", "update", "--init", "--recursive", NULL);
 
+               if (option_shallow_submodules == 1
+                   || (option_shallow_submodules == -1 && option_depth))
+                       argv_array_push(&args, "--depth=1");
+
                if (max_jobs != -1)
                        argv_array_pushf(&args, "--jobs=%d", max_jobs);
 
diff --git a/t/t5614-clone-submodules.sh b/t/t5614-clone-submodules.sh
new file mode 100755 (executable)
index 0000000..62044c5
--- /dev/null
@@ -0,0 +1,85 @@
+#!/bin/sh
+
+test_description='Test shallow cloning of repos with submodules'
+
+. ./test-lib.sh
+
+pwd=$(pwd)
+
+test_expect_success 'setup' '
+       git checkout -b master &&
+       test_commit commit1 &&
+       test_commit commit2 &&
+       mkdir sub &&
+       (
+               cd sub &&
+               git init &&
+               test_commit subcommit1 &&
+               test_commit subcommit2 &&
+               test_commit subcommit3
+       ) &&
+       git submodule add "file://$pwd/sub" sub &&
+       git commit -m "add submodule"
+'
+
+test_expect_success 'nonshallow clone implies nonshallow submodule' '
+       test_when_finished "rm -rf super_clone" &&
+       git clone --recurse-submodules "file://$pwd/." super_clone &&
+       (
+               cd super_clone &&
+               git log --oneline >lines &&
+               test_line_count = 3 lines
+       ) &&
+       (
+               cd super_clone/sub &&
+               git log --oneline >lines &&
+               test_line_count = 3 lines
+       )
+'
+
+test_expect_success 'shallow clone implies shallow submodule' '
+       test_when_finished "rm -rf super_clone" &&
+       git clone --recurse-submodules --depth 2 "file://$pwd/." super_clone &&
+       (
+               cd super_clone &&
+               git log --oneline >lines &&
+               test_line_count = 2 lines
+       ) &&
+       (
+               cd super_clone/sub &&
+               git log --oneline >lines &&
+               test_line_count = 1 lines
+       )
+'
+
+test_expect_success 'shallow clone with non shallow submodule' '
+       test_when_finished "rm -rf super_clone" &&
+       git clone --recurse-submodules --depth 2 --no-shallow-submodules "file://$pwd/." super_clone &&
+       (
+               cd super_clone &&
+               git log --oneline >lines &&
+               test_line_count = 2 lines
+       ) &&
+       (
+               cd super_clone/sub &&
+               git log --oneline >lines &&
+               test_line_count = 3 lines
+       )
+'
+
+test_expect_success 'non shallow clone with shallow submodule' '
+       test_when_finished "rm -rf super_clone" &&
+       git clone --recurse-submodules --no-local --shallow-submodules "file://$pwd/." super_clone &&
+       (
+               cd super_clone &&
+               git log --oneline >lines &&
+               test_line_count = 3 lines
+       ) &&
+       (
+               cd super_clone/sub &&
+               git log --oneline >lines &&
+               test_line_count = 1 lines
+       )
+'
+
+test_done