diff --git a/lib/platform/git/storage.ts b/lib/platform/git/storage.ts
index 07b9cda6f04162653156c008f364e2cc0347432f..822f4c103f1f39a5b8e16e2868d580b122ce4c24 100644
--- a/lib/platform/git/storage.ts
+++ b/lib/platform/git/storage.ts
@@ -110,7 +110,10 @@ export class Storage {
       const cloneStart = process.hrtime();
       try {
         // clone only the default branch
-        await this._git.clone(config.url, '.', ['--depth=2']);
+        await this._git.clone(config.url, '.', [
+          '--depth=2',
+          '--recurse-submodules',
+        ]);
       } catch (err) /* istanbul ignore next */ {
         logger.debug({ err }, 'git clone error');
         throw new Error('platform-failure');
@@ -241,7 +244,19 @@ export class Storage {
     if (!exists) {
       return [];
     }
-    const files = await this._git!.raw([
+    const submodules: string[] = (
+      (await this._git!.raw([
+        'config',
+        '--file',
+        '.gitmodules',
+        '--get-regexp',
+        'path',
+      ])) || ''
+    )
+      .trim()
+      .split(/[\n\s]/)
+      .filter((_e: string, i: number) => i % 2);
+    const files: string = await this._git!.raw([
       'ls-tree',
       '-r',
       '--name-only',
@@ -251,7 +266,12 @@ export class Storage {
     if (!files) {
       return [];
     }
-    return files.split('\n').filter(Boolean);
+    return files
+      .split('\n')
+      .filter(Boolean)
+      .filter((file: string) =>
+        submodules.every((submodule: string) => !file.startsWith(submodule))
+      );
   }
 
   async branchExists(branchName: string) {
diff --git a/test/platform/git/__snapshots__/storage.spec.ts.snap b/test/platform/git/__snapshots__/storage.spec.ts.snap
index 0e86ff4242ddaa10d449124d77a5781db1723893..bc7b2e88b0de37661d62a463e1962c519b9f3e6b 100644
--- a/test/platform/git/__snapshots__/storage.spec.ts.snap
+++ b/test/platform/git/__snapshots__/storage.spec.ts.snap
@@ -11,6 +11,15 @@ Array [
 
 exports[`platform/git/storage getFile(filePath, branchName) returns null for 404 1`] = `[Error: repository-changed]`;
 
+exports[`platform/git/storage getFileList() should exclude submodules 1`] = `
+Array [
+  ".gitmodules",
+  "file_to_delete",
+  "master_file",
+  "past_file",
+]
+`;
+
 exports[`platform/git/storage getFileList() should return the correct files 1`] = `
 Array [
   "file_to_delete",
diff --git a/test/platform/git/storage.spec.ts b/test/platform/git/storage.spec.ts
index b9a8d184bcd1e660376d9e59f4f6157c27516aab..ffc0574a8d44c5425ad6009e1cc9996f400e1394 100644
--- a/test/platform/git/storage.spec.ts
+++ b/test/platform/git/storage.spec.ts
@@ -84,6 +84,18 @@ describe('platform/git/storage', () => {
       expect(await git.getFileList('renovate/future_branch')).toMatchSnapshot();
       expect(await git.getFileList()).toMatchSnapshot();
     });
+    it('should exclude submodules', async () => {
+      const repo = await Git(base.path).silent(true);
+      await repo.submoduleAdd(base.path, 'submodule');
+      await repo.commit('Add submodule');
+      await git.initRepo({
+        localDir: tmpDir.path,
+        url: base.path,
+      });
+      expect(await fs.exists(tmpDir.path + '/.gitmodules')).toBeTruthy();
+      expect(await git.getFileList()).toMatchSnapshot();
+      repo.reset(['--hard', 'HEAD^']);
+    });
   });
   describe('branchExists(branchName)', () => {
     it('should return true if found', async () => {