Repository: buildbot/buildbot

Issue:
shallow _fullClone of submodule fails
Hi,
we have this Git step in our builder:
```
steps.Git(
	name='pull',
	description='git clone project',
	repourl=ssh_url,
	branch='main',
	submodules=True,
	shallow=True,
	mode='incremental',
	sshPrivateKey=util.Secret('ssh_private_key'),
	sshKnownHosts=util.Secret('ssh_known_hosts'),
	haltOnFailure=True
)
```

When we start with a clean build directory on the worker, the shallow submodule clone fails:
```
git -c 'core.sshCommand=ssh -o "BatchMode=yes" -i "/buildbot/.build_hst.build.buildbot/ssh-key" -o "UserKnownHostsFile=/buildbot/.build_hst.build.buildbot/ssh-known-hosts"' submodule update --init --recursive --depth 0
...
fatal: depth 0 is not a positive number
```

I tried to investigate the issue and under this specific scenario, the [shallowClone parameter of the _fullClone function](https://github.com/buildbot/buildbot/blob/d7792c496765dfa0751d2daaf35a33ae4d9a8886/master/buildbot/steps/source/git.py#L446) is not set correctly. `self.shallow=True` while `shallowClone=False`.

Cheers,
Jan


Discussion:

Resolving patch:
diff --git a/master/buildbot/steps/source/git.py b/master/buildbot/steps/source/git.py
--- a/master/buildbot/steps/source/git.py
+++ b/master/buildbot/steps/source/git.py
@@ -114,7 +114,7 @@ def __init__(self, repourl=None, branch='HEAD', mode='incremental', method=None,
                     bbconfig.error("Git: invalid method for mode 'full'.")
                 if self.shallow and (self.mode != 'full' or self.method != 'clobber'):
                     bbconfig.error(
-                        "Git: shallow only possible with mode 'full' and method 'clobber'.")
+                        "Git: in mode 'full' shallow only possible with method 'clobber'.")
         if not isinstance(self.getDescription, (bool, dict)):
             bbconfig.error("Git: getDescription must be a boolean or a dict.")
 
@@ -442,7 +442,7 @@ def _fullClone(self, shallowClone=False):
             cmdArgs = ["submodule", "update", "--init", "--recursive"]
             if self.remoteSubmodules:
                 cmdArgs.append("--remote")
-            if self.shallow:
+            if shallowClone:
                 cmdArgs.extend(["--depth", str(int(shallowClone))])
             res = yield self._dovccmd(cmdArgs, shallowClone)
 


Test patch:
diff --git a/master/buildbot/test/unit/steps/test_source_git.py b/master/buildbot/test/unit/steps/test_source_git.py
--- a/master/buildbot/test/unit/steps/test_source_git.py
+++ b/master/buildbot/test/unit/steps/test_source_git.py
@@ -1712,6 +1712,38 @@ def test_mode_incremental_branch_ssh_key_2_10(self):
             'got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', self.sourceName)
         return self.run_step()
 
+    def test_mode_incremental_no_existing_repo_shallow_submodules(self):
+        self.setup_step(
+            self.stepClass(repourl='http://github.com/buildbot/buildbot.git',
+                           mode='incremental', shallow=True, submodules=True))
+
+        self.expect_commands(
+            ExpectShell(workdir='wkdir',
+                        command=['git', '--version'])
+            .stdout('git version 1.7.5')
+            .exit(0),
+            ExpectStat(file='wkdir/.buildbot-patched', log_environ=True)
+            .exit(1),
+            ExpectListdir(dir='wkdir')
+            .exit(0),
+            ExpectShell(workdir='wkdir',
+                        command=['git', 'clone',
+                                 'http://github.com/buildbot/buildbot.git',
+                                 '.', '--progress'])
+            .exit(0),
+            ExpectShell(workdir='wkdir',
+                        command=['git', 'submodule', 'update', '--init', '--recursive'])
+            .exit(0),
+            ExpectShell(workdir='wkdir',
+                        command=['git', 'rev-parse', 'HEAD'])
+            .stdout('f6ad368298bd941e934a41f3babc827b2aa95a1d')
+            .exit(0)
+        )
+        self.expect_outcome(result=SUCCESS)
+        self.expect_property(
+            'got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', self.sourceName)
+        return self.run_step()
+
     def test_mode_full_fresh(self):
         self.setup_step(
             self.stepClass(repourl='http://github.com/buildbot/buildbot.git',
@@ -2334,7 +2366,7 @@ def test_mode_full_copy_ssh_key_2_10(self):
 
     def test_mode_full_copy_shallow(self):
         with self.assertRaisesConfigError(
-                "shallow only possible with mode 'full' and method 'clobber'"):
+                "in mode 'full' shallow only possible with method 'clobber'"):
             self.stepClass(repourl='http://github.com/buildbot/buildbot.git',
                         mode='full', method='copy', shallow=True)