Skip to content

Commit d22eb04

Browse files
stefanbellergitster
authored andcommitted
clone: add --shallow-submodules flag
When creating a shallow clone of a repository with submodules, the depth argument does not influence the submodules, i.e. the submodules are done as non-shallow clones. It is unclear what the best default is for the depth of submodules of a shallow clone, so we need to have the possibility to do all kinds of combinations: * shallow super project with shallow submodules e.g. build bots starting always from scratch. They want to transmit the least amount of network data as well as using the least amount of space on their hard drive. * shallow super project with unshallow submodules e.g. The superproject is just there to track a collection of repositories and it is not important to have the relationship between the repositories intact. However the history of the individual submodules matter. * unshallow super project with shallow submodules e.g. The superproject is the actual project and the submodule is a library which is rarely touched. The new switch to select submodules to be shallow or unshallow supports all of these three cases. It is easy to transition from the first to the second case by just unshallowing the submodules (`git submodule foreach git fetch --unshallow`), but it is not possible to transition from the second to the first case (as we would have already transmitted the non shallow over the network). That is why we want to make the first case the default in case of a shallow super project. This leads to the inconvenience in the second case with the shallow super project and unshallow submodules, as you need to pass `--no-shallow-submodules`. Signed-off-by: Stefan Beller <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 72290d6 commit d22eb04

File tree

3 files changed

+102
-3
lines changed

3 files changed

+102
-3
lines changed

Documentation/git-clone.txt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ SYNOPSIS
1414
[-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
1515
[--dissociate] [--separate-git-dir <git dir>]
1616
[--depth <depth>] [--[no-]single-branch]
17-
[--recursive | --recurse-submodules] [--jobs <n>] [--] <repository>
18-
[<directory>]
17+
[--recursive | --recurse-submodules] [--[no-]shallow-submodules]
18+
[--jobs <n>] [--] <repository> [<directory>]
1919

2020
DESCRIPTION
2121
-----------
@@ -190,7 +190,11 @@ objects from the source repository into a pack in the cloned repository.
190190

191191
--depth <depth>::
192192
Create a 'shallow' clone with a history truncated to the
193-
specified number of revisions.
193+
specified number of revisions. Implies `--single-branch` unless
194+
`--no-single-branch` is given to fetch the histories near the
195+
tips of all branches. This implies `--shallow-submodules`. If
196+
you want to have a shallow superproject clone, but full submodules,
197+
also pass `--no-shallow-submodules`.
194198

195199
--[no-]single-branch::
196200
Clone only the history leading to the tip of a single branch,
@@ -214,6 +218,9 @@ objects from the source repository into a pack in the cloned repository.
214218
repository does not have a worktree/checkout (i.e. if any of
215219
`--no-checkout`/`-n`, `--bare`, or `--mirror` is given)
216220

221+
--[no-]shallow-submodules::
222+
All submodules which are cloned will be shallow with a depth of 1.
223+
217224
--separate-git-dir=<git dir>::
218225
Instead of placing the cloned repository where it is supposed
219226
to be, place the cloned repository at the specified directory,

builtin/clone.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ static const char * const builtin_clone_usage[] = {
4040

4141
static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1;
4242
static int option_local = -1, option_no_hardlinks, option_shared, option_recursive;
43+
static int option_shallow_submodules = -1;
4344
static char *option_template, *option_depth;
4445
static char *option_origin = NULL;
4546
static char *option_branch = NULL;
@@ -91,6 +92,8 @@ static struct option builtin_clone_options[] = {
9192
N_("create a shallow clone of that depth")),
9293
OPT_BOOL(0, "single-branch", &option_single_branch,
9394
N_("clone only one branch, HEAD or --branch")),
95+
OPT_BOOL(0, "shallow-submodules", &option_shallow_submodules,
96+
N_("any cloned submodules will be shallow")),
9497
OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
9598
N_("separate git dir from working tree")),
9699
OPT_STRING_LIST('c', "config", &option_config, N_("key=value"),
@@ -727,6 +730,10 @@ static int checkout(void)
727730
struct argv_array args = ARGV_ARRAY_INIT;
728731
argv_array_pushl(&args, "submodule", "update", "--init", "--recursive", NULL);
729732

733+
if (option_shallow_submodules == 1
734+
|| (option_shallow_submodules == -1 && option_depth))
735+
argv_array_push(&args, "--depth=1");
736+
730737
if (max_jobs != -1)
731738
argv_array_pushf(&args, "--jobs=%d", max_jobs);
732739

t/t5614-clone-submodules.sh

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/bin/sh
2+
3+
test_description='Test shallow cloning of repos with submodules'
4+
5+
. ./test-lib.sh
6+
7+
pwd=$(pwd)
8+
9+
test_expect_success 'setup' '
10+
git checkout -b master &&
11+
test_commit commit1 &&
12+
test_commit commit2 &&
13+
mkdir sub &&
14+
(
15+
cd sub &&
16+
git init &&
17+
test_commit subcommit1 &&
18+
test_commit subcommit2 &&
19+
test_commit subcommit3
20+
) &&
21+
git submodule add "file://$pwd/sub" sub &&
22+
git commit -m "add submodule"
23+
'
24+
25+
test_expect_success 'nonshallow clone implies nonshallow submodule' '
26+
test_when_finished "rm -rf super_clone" &&
27+
git clone --recurse-submodules "file://$pwd/." super_clone &&
28+
(
29+
cd super_clone &&
30+
git log --oneline >lines &&
31+
test_line_count = 3 lines
32+
) &&
33+
(
34+
cd super_clone/sub &&
35+
git log --oneline >lines &&
36+
test_line_count = 3 lines
37+
)
38+
'
39+
40+
test_expect_success 'shallow clone implies shallow submodule' '
41+
test_when_finished "rm -rf super_clone" &&
42+
git clone --recurse-submodules --depth 2 "file://$pwd/." super_clone &&
43+
(
44+
cd super_clone &&
45+
git log --oneline >lines &&
46+
test_line_count = 2 lines
47+
) &&
48+
(
49+
cd super_clone/sub &&
50+
git log --oneline >lines &&
51+
test_line_count = 1 lines
52+
)
53+
'
54+
55+
test_expect_success 'shallow clone with non shallow submodule' '
56+
test_when_finished "rm -rf super_clone" &&
57+
git clone --recurse-submodules --depth 2 --no-shallow-submodules "file://$pwd/." super_clone &&
58+
(
59+
cd super_clone &&
60+
git log --oneline >lines &&
61+
test_line_count = 2 lines
62+
) &&
63+
(
64+
cd super_clone/sub &&
65+
git log --oneline >lines &&
66+
test_line_count = 3 lines
67+
)
68+
'
69+
70+
test_expect_success 'non shallow clone with shallow submodule' '
71+
test_when_finished "rm -rf super_clone" &&
72+
git clone --recurse-submodules --no-local --shallow-submodules "file://$pwd/." super_clone &&
73+
(
74+
cd super_clone &&
75+
git log --oneline >lines &&
76+
test_line_count = 3 lines
77+
) &&
78+
(
79+
cd super_clone/sub &&
80+
git log --oneline >lines &&
81+
test_line_count = 1 lines
82+
)
83+
'
84+
85+
test_done

0 commit comments

Comments
 (0)