Skip to content

Commit 02b4019

Browse files
committed
Add support and tests for clone --recurse-submodules
Including tests for clone --recursive.
1 parent a86f238 commit 02b4019

3 files changed

Lines changed: 70 additions & 11 deletions

File tree

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ jobs:
119119
run: |
120120
git config --global user.email test@yadm.io
121121
git config --global user.name "Yadm Test"
122+
git config --global protocol.file.allow always
122123
123124
dos2unix yadm.1 .github/workflows/*.yml test/pinentry-mock
124125
chmod +x test/pinentry-mock

test/test_clone.py

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,39 @@ def test_clone(runner, paths, yadm_cmd, repo_config, ds1, good_remote, repo_exis
108108
assert old_repo.exists()
109109

110110

111+
@pytest.mark.usefixtures("remote_with_submodules")
112+
@pytest.mark.parametrize("action", ["recursive", "recurse", "specific"])
113+
def test_clone_submodules(runner, paths, yadm_cmd, repo_config, action):
114+
"""Test clone operation with submodules"""
115+
116+
# clear out the work path
117+
paths.work.remove()
118+
paths.work.mkdir()
119+
120+
env = {
121+
"GIT_CONFIG_COUNT": "1",
122+
"GIT_CONFIG_KEY_0": "protocol.file.allow",
123+
"GIT_CONFIG_VALUE_0": "always",
124+
}
125+
126+
args = ["clone", "-w", paths.work]
127+
if action == "recursive":
128+
args += ["--recursive"]
129+
elif action == "recurse":
130+
args += ["--recurse-submodules"]
131+
elif action == "specific":
132+
args += ["--recurse-submodules=a", "--recurse-submodules=d1/c"]
133+
args += [f"file://{paths.remote}"]
134+
run = runner(command=yadm_cmd(*args), env=env)
135+
assert successful_clone(run, paths, repo_config)
136+
137+
for path in ("a", "b", "d1/c"):
138+
if action != "specific" or path != "b":
139+
assert paths.work.join(path).join(".git").exists()
140+
else:
141+
assert not paths.work.join(path).join(".git").exists()
142+
143+
111144
@pytest.mark.usefixtures("remote")
112145
@pytest.mark.parametrize(
113146
"bs_exists, bs_param, answer",
@@ -305,16 +338,38 @@ def remote(paths, ds1_repo_copy):
305338
"""Function scoped remote (based on ds1)"""
306339
# pylint: disable=unused-argument
307340
# This is ignored because
308-
# @pytest.mark.usefixtures('ds1_remote_copy')
341+
# @pytest.mark.usefixtures('ds1_repo_copy')
309342
# cannot be applied to another fixture.
310343
paths.remote.remove()
311344
paths.repo.move(paths.remote)
312345

313346

314-
def test_no_repo(
315-
runner,
316-
yadm_cmd,
317-
):
347+
@pytest.fixture()
348+
def remote_with_submodules(tmpdir_factory, runner, paths, remote, ds1_work_copy):
349+
"""Function scoped remote with submodules (based on ds1)"""
350+
# pylint: disable=unused-argument
351+
# This is ignored because
352+
# @pytest.mark.usefixtures('remote', 'ds1_work_copy')
353+
# cannot be applied to another fixture.
354+
submodule = tmpdir_factory.mktemp("submodule")
355+
paths.remote.copy(submodule)
356+
357+
env = os.environ.copy()
358+
env["GIT_DIR"] = str(paths.remote)
359+
360+
for path in ("a", "b", "d1/c"):
361+
run = runner(
362+
["git", "-C", paths.work, "-c", "protocol.file.allow=always", "submodule", "add", submodule, path],
363+
env=env,
364+
report=False,
365+
)
366+
assert run.success
367+
368+
run = runner(["git", "-C", paths.work, "commit", "-m", '"Add submodules"'], env=env, report=False)
369+
assert run.success
370+
371+
372+
def test_no_repo(runner, yadm_cmd):
318373
"""Test cloning without specifying a repo"""
319374
run = runner(command=yadm_cmd("clone", "-f"))
320375
assert run.failure

yadm

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ function clone() {
754754
DO_BOOTSTRAP=1
755755
local -a args
756756
local -i do_checkout=1
757-
local -i do_submodules=0
757+
local -a submodules
758758
while [[ $# -gt 0 ]]; do
759759
case "$1" in
760760
--bootstrap) # force bootstrap, without prompt
@@ -769,10 +769,13 @@ function clone() {
769769
-n | --no-checkout)
770770
do_checkout=0
771771
;;
772-
--recursive)
773-
do_submodules=1
772+
--recursive | --recurse-submodules)
773+
submodules+=(":/")
774+
;;
775+
--recurse-submodules=*)
776+
submodules+=(":/${1#*=}")
774777
;;
775-
--bare | --mirror | --recurse-submodules* | --separate-git-dir=*)
778+
--bare | --mirror | --separate-git-dir=*)
776779
# ignore arguments without separate parameter
777780
;;
778781
--separate-git-dir)
@@ -839,8 +842,8 @@ function clone() {
839842
"$GIT_PROGRAM" checkout -- ":/$file"
840843
done
841844

842-
if [[ $do_submodules -ne 0 ]]; then
843-
"$GIT_PROGRAM" submodule update --init --recursive
845+
if [ ${#submodules[@]} -gt 0 ]; then
846+
"$GIT_PROGRAM" submodule update --init --recursive -- "${submodules[@]}"
844847
fi
845848

846849
if [ -n "$("$GIT_PROGRAM" ls-files --modified)" ]; then

0 commit comments

Comments
 (0)