diff --git a/lib/manager/cargo/artifacts.spec.ts b/lib/manager/cargo/artifacts.spec.ts
index 8d1cbd004dd53fde2d1e36a7b359073954df6858..92fb548a641e37f29dac5404019f3c234accc610 100644
--- a/lib/manager/cargo/artifacts.spec.ts
+++ b/lib/manager/cargo/artifacts.spec.ts
@@ -2,7 +2,7 @@ import { exec as _exec } from 'child_process';
 import _fs from 'fs-extra';
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../test/execUtil';
-import { mocked, platform } from '../../../test/util';
+import { git, mocked } from '../../../test/util';
 import { setExecConfig } from '../../util/exec';
 import { BinarySource } from '../../util/exec/common';
 import * as docker from '../../util/exec/docker';
@@ -12,6 +12,7 @@ import * as cargo from './artifacts';
 jest.mock('fs-extra');
 jest.mock('child_process');
 jest.mock('../../util/exec/env');
+jest.mock('../../util/git');
 jest.mock('../../util/http');
 
 const fs: jest.Mocked<typeof _fs> = _fs as any;
@@ -70,7 +71,7 @@ describe('.updateArtifacts()', () => {
     expect(execSnapshots).toMatchSnapshot();
   });
   it('returns updated Cargo.lock', async () => {
-    platform.getFile.mockResolvedValueOnce('Old Cargo.lock');
+    git.getFile.mockResolvedValueOnce('Old Cargo.lock');
     const execSnapshots = mockExecAll(exec);
     fs.readFile.mockResolvedValueOnce('New Cargo.lock' as any);
     const updatedDeps = ['dep1'];
@@ -87,7 +88,7 @@ describe('.updateArtifacts()', () => {
   it('returns updated Cargo.lock with docker', async () => {
     jest.spyOn(docker, 'removeDanglingContainers').mockResolvedValueOnce();
     await setExecConfig({ ...config, binarySource: BinarySource.Docker });
-    platform.getFile.mockResolvedValueOnce('Old Cargo.lock');
+    git.getFile.mockResolvedValueOnce('Old Cargo.lock');
     const execSnapshots = mockExecAll(exec);
     fs.readFile.mockResolvedValueOnce('New Cargo.lock' as any);
     const updatedDeps = ['dep1'];
diff --git a/lib/manager/npm/post-update/index.ts b/lib/manager/npm/post-update/index.ts
index e045777b4fa4b9cc5d3e83a78b15e28be3c90d3c..072f947eb1c3973bd395a65237009c13f3a6d306 100644
--- a/lib/manager/npm/post-update/index.ts
+++ b/lib/manager/npm/post-update/index.ts
@@ -16,7 +16,7 @@ import { platform } from '../../../platform';
 import { ExternalHostError } from '../../../types/errors/external-host-error';
 import { getChildProcessEnv } from '../../../util/exec/env';
 import { deleteLocalFile } from '../../../util/fs';
-import { getRepoStatus } from '../../../util/git';
+import { getFile, getRepoStatus } from '../../../util/git';
 import * as hostRules from '../../../util/host-rules';
 import { PackageFile, PostUpdateConfig, Upgrade } from '../../common';
 import * as lerna from './lerna';
@@ -172,7 +172,7 @@ export async function writeExistingFiles(
         await remove(npmLockPath);
       } else {
         logger.debug(`Writing ${npmLock}`);
-        let existingNpmLock = await platform.getFile(npmLock);
+        let existingNpmLock = await getFile(npmLock);
         const widens = [];
         for (const upgrade of config.upgrades) {
           if (
@@ -450,7 +450,7 @@ export async function getAdditionalFiles(
         stderr: res.stderr,
       });
     } else {
-      const existingContent = await platform.getFile(
+      const existingContent = await getFile(
         lockFile,
         config.reuseExistingBranch ? config.branchName : config.baseBranch
       );
@@ -516,7 +516,7 @@ export async function getAdditionalFiles(
         stderr: res.stderr,
       });
     } else {
-      const existingContent = await platform.getFile(
+      const existingContent = await getFile(
         lockFileName,
         config.reuseExistingBranch ? config.branchName : config.baseBranch
       );
@@ -528,9 +528,7 @@ export async function getAdditionalFiles(
         });
         // istanbul ignore next
         try {
-          const yarnrc = await platform.getFile(
-            upath.join(lockFileDir, '.yarnrc')
-          );
+          const yarnrc = await getFile(upath.join(lockFileDir, '.yarnrc'));
           if (yarnrc) {
             const mirrorLine = yarnrc
               .split('\n')
@@ -618,7 +616,7 @@ export async function getAdditionalFiles(
         stderr: res.stderr,
       });
     } else {
-      const existingContent = await platform.getFile(
+      const existingContent = await getFile(
         lockFile,
         config.reuseExistingBranch ? config.branchName : config.baseBranch
       );
@@ -716,7 +714,7 @@ export async function getAdditionalFiles(
       for (const packageFile of packageFiles.npm) {
         const filename = packageFile.npmLock || packageFile.yarnLock;
         logger.trace('Checking for ' + filename);
-        const existingContent = await platform.getFile(
+        const existingContent = await getFile(
           filename,
           config.reuseExistingBranch ? config.branchName : config.baseBranch
         );
diff --git a/lib/manager/npm/post-update/lerna.spec.ts b/lib/manager/npm/post-update/lerna.spec.ts
index 49cc2015a24030b6d6b935121c55ad5b0c82eaab..b626c53fd6dd94906acbaa973f6aea8d08f07801 100644
--- a/lib/manager/npm/post-update/lerna.spec.ts
+++ b/lib/manager/npm/post-update/lerna.spec.ts
@@ -1,18 +1,17 @@
 import { exec as _exec } from 'child_process';
 import { envMock, mockExecAll } from '../../../../test/execUtil';
-import { mocked } from '../../../../test/util';
-import { platform as _platform } from '../../../platform';
+import { git, mocked } from '../../../../test/util';
 import * as _env from '../../../util/exec/env';
 import * as _lernaHelper from './lerna';
 
 jest.mock('child_process');
 jest.mock('../../../util/exec/env');
+jest.mock('../../../util/git');
 jest.mock('../../../manager/npm/post-update/node-version');
 
 const exec: jest.Mock<typeof _exec> = _exec as any;
 const env = mocked(_env);
 const lernaHelper = mocked(_lernaHelper);
-const platform = mocked(_platform);
 
 describe('generateLockFiles()', () => {
   beforeEach(() => {
@@ -34,7 +33,7 @@ describe('generateLockFiles()', () => {
     expect(res.error).toBe(false);
   });
   it('generates package-lock.json files', async () => {
-    platform.getFile.mockResolvedValueOnce(
+    git.getFile.mockResolvedValueOnce(
       JSON.stringify({ dependencies: { lerna: '2.0.0' } })
     );
     const execSnapshots = mockExecAll(exec);
@@ -50,7 +49,7 @@ describe('generateLockFiles()', () => {
     expect(execSnapshots).toMatchSnapshot();
   });
   it('performs full npm install', async () => {
-    platform.getFile.mockResolvedValueOnce(
+    git.getFile.mockResolvedValueOnce(
       JSON.stringify({ dependencies: { lerna: '2.0.0' } })
     );
     const execSnapshots = mockExecAll(exec);
@@ -66,7 +65,7 @@ describe('generateLockFiles()', () => {
     expect(execSnapshots).toMatchSnapshot();
   });
   it('generates yarn.lock files', async () => {
-    platform.getFile.mockResolvedValueOnce(
+    git.getFile.mockResolvedValueOnce(
       JSON.stringify({ devDependencies: { lerna: '2.0.0' } })
     );
     const execSnapshots = mockExecAll(exec);
@@ -80,14 +79,14 @@ describe('generateLockFiles()', () => {
     expect(res.error).toBe(false);
   });
   it('defaults to latest', async () => {
-    platform.getFile.mockReturnValueOnce(undefined);
+    git.getFile.mockReturnValueOnce(undefined);
     const execSnapshots = mockExecAll(exec);
     const res = await lernaHelper.generateLockFiles('npm', 'some-dir', {}, {});
     expect(res.error).toBe(false);
     expect(execSnapshots).toMatchSnapshot();
   });
   it('maps dot files', async () => {
-    platform.getFile.mockReturnValueOnce(undefined);
+    git.getFile.mockReturnValueOnce(undefined);
     const execSnapshots = mockExecAll(exec);
     const res = await lernaHelper.generateLockFiles(
       'npm',
@@ -102,7 +101,7 @@ describe('generateLockFiles()', () => {
     expect(execSnapshots).toMatchSnapshot();
   });
   it('allows scripts for trust level high', async () => {
-    platform.getFile.mockReturnValueOnce(undefined);
+    git.getFile.mockReturnValueOnce(undefined);
     const execSnapshots = mockExecAll(exec);
     global.trustLevel = 'high';
     const res = await lernaHelper.generateLockFiles('npm', 'some-dir', {}, {});
diff --git a/lib/manager/npm/post-update/lerna.ts b/lib/manager/npm/post-update/lerna.ts
index 2a7607ecf96b17c4c688b85d6235356cbe3a0168..dbf1fa5a91e46a117a36eac9ebb7f21163207773 100644
--- a/lib/manager/npm/post-update/lerna.ts
+++ b/lib/manager/npm/post-update/lerna.ts
@@ -2,8 +2,8 @@ import semver, { validRange } from 'semver';
 import { quote } from 'shlex';
 import { join } from 'upath';
 import { logger } from '../../../logger';
-import { platform } from '../../../platform';
 import { ExecOptions, exec } from '../../../util/exec';
+import { getFile } from '../../../util/git';
 import { PostUpdateConfig } from '../../common';
 import { getNodeConstraint } from './node-version';
 import { optimizeCommand } from './yarn';
@@ -84,7 +84,7 @@ export async function generateLockFiles(
     cmd.push(`${lernaClient} install ${cmdOptions}`);
     let lernaVersion: string;
     try {
-      const pJson = JSON.parse(await platform.getFile('package.json'));
+      const pJson = JSON.parse(await getFile('package.json'));
       lernaVersion =
         (pJson.dependencies && pJson.dependencies.lerna) ||
         (pJson.devDependencies && pJson.devDependencies.lerna);
diff --git a/lib/platform/__snapshots__/index.spec.ts.snap b/lib/platform/__snapshots__/index.spec.ts.snap
index c14467a75f03cf60eab97edd2acde0a06505858e..f2e74e054fbf70904cc6cc495e18b728e3044f29 100644
--- a/lib/platform/__snapshots__/index.spec.ts.snap
+++ b/lib/platform/__snapshots__/index.spec.ts.snap
@@ -23,8 +23,6 @@ Array [
   "getBranchStatus",
   "getBranchStatusCheck",
   "getCommitMessages",
-  "getFile",
-  "getFileList",
   "getIssueList",
   "getPr",
   "getPrBody",
@@ -66,8 +64,6 @@ Array [
   "getBranchStatus",
   "getBranchStatusCheck",
   "getCommitMessages",
-  "getFile",
-  "getFileList",
   "getIssueList",
   "getPr",
   "getPrBody",
@@ -109,8 +105,6 @@ Array [
   "getBranchStatus",
   "getBranchStatusCheck",
   "getCommitMessages",
-  "getFile",
-  "getFileList",
   "getIssueList",
   "getPr",
   "getPrBody",
@@ -152,8 +146,6 @@ Array [
   "getBranchStatus",
   "getBranchStatusCheck",
   "getCommitMessages",
-  "getFile",
-  "getFileList",
   "getIssueList",
   "getPr",
   "getPrBody",
diff --git a/lib/platform/azure/index.ts b/lib/platform/azure/index.ts
index 14b50d0acd2629d17eee2e3cc74631d29d106c3d..cb1c8530368c5a59f1085d1b6157b57b60212df9 100644
--- a/lib/platform/azure/index.ts
+++ b/lib/platform/azure/index.ts
@@ -184,10 +184,6 @@ export function getRepoForceRebase(): Promise<boolean> {
 
 // Search
 
-export /* istanbul ignore next */ function getFileList(): Promise<string[]> {
-  return git.getFileList();
-}
-
 export /* istanbul ignore next */ async function setBaseBranch(
   branchName = config.baseBranch
 ): Promise<string> {
@@ -224,13 +220,6 @@ export /* istanbul ignore next */ function isBranchStale(
   return git.isBranchStale(branchName);
 }
 
-export /* istanbul ignore next */ function getFile(
-  filePath: string,
-  branchName: string
-): Promise<string> {
-  return git.getFile(filePath, branchName);
-}
-
 // istanbul ignore next
 async function abandonPr(prNo: number): Promise<void> {
   logger.debug(`abandonPr(prNo)(${prNo})`);
diff --git a/lib/platform/bitbucket-server/__snapshots__/index.spec.ts.snap b/lib/platform/bitbucket-server/__snapshots__/index.spec.ts.snap
index d0f10c2bb9a95ebd4edf931b247070d9db8b3a5a..3da1444b7a1322447050e5c6a6a328194fd8b764 100644
--- a/lib/platform/bitbucket-server/__snapshots__/index.spec.ts.snap
+++ b/lib/platform/bitbucket-server/__snapshots__/index.spec.ts.snap
@@ -546,37 +546,6 @@ Array [
 ]
 `;
 
-exports[`platform/bitbucket-server endpoint with no path branchExists() getFileList() sends to gitFs 1`] = `true`;
-
-exports[`platform/bitbucket-server endpoint with no path branchExists() getFileList() sends to gitFs 2`] = `
-Array [
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "stash.renovatebot.com",
-      "user-agent": "https://github.com/renovatebot/renovate",
-      "x-atlassian-token": "no-check",
-    },
-    "method": "GET",
-    "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo",
-  },
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "stash.renovatebot.com",
-      "user-agent": "https://github.com/renovatebot/renovate",
-      "x-atlassian-token": "no-check",
-    },
-    "method": "GET",
-    "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo/branches/default",
-  },
-]
-`;
-
 exports[`platform/bitbucket-server endpoint with no path commitFiles() sends to gitFs 1`] = `
 Array [
   Object {
@@ -2112,68 +2081,6 @@ Array [
 ]
 `;
 
-exports[`platform/bitbucket-server endpoint with no path getFile() sends to gitFs 1`] = `undefined`;
-
-exports[`platform/bitbucket-server endpoint with no path getFile() sends to gitFs 2`] = `
-Array [
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "stash.renovatebot.com",
-      "user-agent": "https://github.com/renovatebot/renovate",
-      "x-atlassian-token": "no-check",
-    },
-    "method": "GET",
-    "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo",
-  },
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "stash.renovatebot.com",
-      "user-agent": "https://github.com/renovatebot/renovate",
-      "x-atlassian-token": "no-check",
-    },
-    "method": "GET",
-    "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo/branches/default",
-  },
-]
-`;
-
-exports[`platform/bitbucket-server endpoint with no path getFileList() sends to gitFs 1`] = `undefined`;
-
-exports[`platform/bitbucket-server endpoint with no path getFileList() sends to gitFs 2`] = `
-Array [
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "stash.renovatebot.com",
-      "user-agent": "https://github.com/renovatebot/renovate",
-      "x-atlassian-token": "no-check",
-    },
-    "method": "GET",
-    "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo",
-  },
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "stash.renovatebot.com",
-      "user-agent": "https://github.com/renovatebot/renovate",
-      "x-atlassian-token": "no-check",
-    },
-    "method": "GET",
-    "url": "https://stash.renovatebot.com/rest/api/1.0/projects/SOME/repos/repo/branches/default",
-  },
-]
-`;
-
 exports[`platform/bitbucket-server endpoint with no path getPr() canRebase 1`] = `
 Object {
   "body": "* Line 1
@@ -4697,37 +4604,6 @@ Array [
 ]
 `;
 
-exports[`platform/bitbucket-server endpoint with path branchExists() getFileList() sends to gitFs 1`] = `true`;
-
-exports[`platform/bitbucket-server endpoint with path branchExists() getFileList() sends to gitFs 2`] = `
-Array [
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "stash.renovatebot.com",
-      "user-agent": "https://github.com/renovatebot/renovate",
-      "x-atlassian-token": "no-check",
-    },
-    "method": "GET",
-    "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo",
-  },
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "stash.renovatebot.com",
-      "user-agent": "https://github.com/renovatebot/renovate",
-      "x-atlassian-token": "no-check",
-    },
-    "method": "GET",
-    "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo/branches/default",
-  },
-]
-`;
-
 exports[`platform/bitbucket-server endpoint with path commitFiles() sends to gitFs 1`] = `
 Array [
   Object {
@@ -6263,68 +6139,6 @@ Array [
 ]
 `;
 
-exports[`platform/bitbucket-server endpoint with path getFile() sends to gitFs 1`] = `undefined`;
-
-exports[`platform/bitbucket-server endpoint with path getFile() sends to gitFs 2`] = `
-Array [
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "stash.renovatebot.com",
-      "user-agent": "https://github.com/renovatebot/renovate",
-      "x-atlassian-token": "no-check",
-    },
-    "method": "GET",
-    "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo",
-  },
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "stash.renovatebot.com",
-      "user-agent": "https://github.com/renovatebot/renovate",
-      "x-atlassian-token": "no-check",
-    },
-    "method": "GET",
-    "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo/branches/default",
-  },
-]
-`;
-
-exports[`platform/bitbucket-server endpoint with path getFileList() sends to gitFs 1`] = `undefined`;
-
-exports[`platform/bitbucket-server endpoint with path getFileList() sends to gitFs 2`] = `
-Array [
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "stash.renovatebot.com",
-      "user-agent": "https://github.com/renovatebot/renovate",
-      "x-atlassian-token": "no-check",
-    },
-    "method": "GET",
-    "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo",
-  },
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "stash.renovatebot.com",
-      "user-agent": "https://github.com/renovatebot/renovate",
-      "x-atlassian-token": "no-check",
-    },
-    "method": "GET",
-    "url": "https://stash.renovatebot.com/vcs/rest/api/1.0/projects/SOME/repos/repo/branches/default",
-  },
-]
-`;
-
 exports[`platform/bitbucket-server endpoint with path getPr() canRebase 1`] = `
 Object {
   "body": "* Line 1
diff --git a/lib/platform/bitbucket-server/index.spec.ts b/lib/platform/bitbucket-server/index.spec.ts
index 7b5a659695c436315fe4ea80547c782ef9fceb42..f6fb4eb626e0b936cd6c412b63c727e427ca2027 100644
--- a/lib/platform/bitbucket-server/index.spec.ts
+++ b/lib/platform/bitbucket-server/index.spec.ts
@@ -400,26 +400,6 @@ describe('platform/bitbucket-server', () => {
         });
       });
 
-      describe('getFileList()', () => {
-        it('sends to gitFs', async () => {
-          await initRepo();
-          expect(await bitbucket.getFileList()).toMatchSnapshot();
-          expect(httpMock.getTrace()).toMatchSnapshot();
-        });
-      });
-
-      describe('branchExists()', () => {
-        describe('getFileList()', () => {
-          it('sends to gitFs', async () => {
-            await initRepo();
-            expect(
-              await bitbucket.branchExists(undefined as any)
-            ).toMatchSnapshot();
-            expect(httpMock.getTrace()).toMatchSnapshot();
-          });
-        });
-      });
-
       describe('isBranchStale()', () => {
         it('sends to gitFs', async () => {
           await initRepo();
@@ -467,14 +447,6 @@ describe('platform/bitbucket-server', () => {
         });
       });
 
-      describe('getFile()', () => {
-        it('sends to gitFs', async () => {
-          await initRepo();
-          expect(await bitbucket.getFile('', '')).toMatchSnapshot();
-          expect(httpMock.getTrace()).toMatchSnapshot();
-        });
-      });
-
       describe('getAllRenovateBranches()', () => {
         it('sends to gitFs', async () => {
           await initRepo();
diff --git a/lib/platform/bitbucket-server/index.ts b/lib/platform/bitbucket-server/index.ts
index 100f159e3e1d4a2b7c12bc27bcc0162d260427f2..fa901ac28d1b5e7d172922351230ce1916ff28c2 100644
--- a/lib/platform/bitbucket-server/index.ts
+++ b/lib/platform/bitbucket-server/index.ts
@@ -253,13 +253,6 @@ export /* istanbul ignore next */ function setBranchPrefix(
   return git.setBranchPrefix(branchPrefix);
 }
 
-// Search
-
-// Get full file list
-export function getFileList(): Promise<string[]> {
-  return git.getFileList();
-}
-
 // Branch
 
 // Returns true if branch exists, otherwise false
@@ -447,11 +440,6 @@ export async function commitFiles(
   return commit;
 }
 
-export function getFile(filePath: string, branchName: string): Promise<string> {
-  logger.debug(`getFile(${filePath}, ${branchName})`);
-  return git.getFile(filePath, branchName);
-}
-
 export async function deleteBranch(
   branchName: string,
   closePr = false
diff --git a/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap b/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap
index 486fdd173b8835b4f9181b489bb8b84fbb328806..5bb9d7dac127850981a0a9c54dc960dd7ae7dc39 100644
--- a/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap
+++ b/lib/platform/bitbucket/__snapshots__/index.spec.ts.snap
@@ -64,22 +64,6 @@ Array [
 ]
 `;
 
-exports[`platform/bitbucket branchExists() getFileList() sends to gitFs 1`] = `
-Array [
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "api.bitbucket.org",
-      "user-agent": "https://github.com/renovatebot/renovate",
-    },
-    "method": "GET",
-    "url": "https://api.bitbucket.org/2.0/repositories/some/repo",
-  },
-]
-`;
-
 exports[`platform/bitbucket commitFiles() sends to gitFs 1`] = `undefined`;
 
 exports[`platform/bitbucket commitFiles() sends to gitFs 2`] = `
@@ -989,40 +973,6 @@ Array [
 ]
 `;
 
-exports[`platform/bitbucket getFile() sends to gitFs 1`] = `undefined`;
-
-exports[`platform/bitbucket getFile() sends to gitFs 2`] = `
-Array [
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "api.bitbucket.org",
-      "user-agent": "https://github.com/renovatebot/renovate",
-    },
-    "method": "GET",
-    "url": "https://api.bitbucket.org/2.0/repositories/some/repo",
-  },
-]
-`;
-
-exports[`platform/bitbucket getFileList() sends to gitFs 1`] = `
-Array [
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "authorization": "Basic YWJjOjEyMw==",
-      "host": "api.bitbucket.org",
-      "user-agent": "https://github.com/renovatebot/renovate",
-    },
-    "method": "GET",
-    "url": "https://api.bitbucket.org/2.0/repositories/some/repo",
-  },
-]
-`;
-
 exports[`platform/bitbucket getPr() canRebase 1`] = `
 Object {
   "body": "summary",
diff --git a/lib/platform/bitbucket/index.spec.ts b/lib/platform/bitbucket/index.spec.ts
index 63059d005d57aa402b4fd78d02067902c01a4251..826b11d4e181ae48ed68dd75e9b10efd1735e1d0 100644
--- a/lib/platform/bitbucket/index.spec.ts
+++ b/lib/platform/bitbucket/index.spec.ts
@@ -194,26 +194,6 @@ describe('platform/bitbucket', () => {
     });
   });
 
-  describe('getFileList()', () => {
-    it('sends to gitFs', async () => {
-      await initRepoMock();
-      const fileList = await bitbucket.getFileList();
-      expect(fileList).not.toBeNull();
-      expect(httpMock.getTrace()).toMatchSnapshot();
-    });
-  });
-
-  describe('branchExists()', () => {
-    describe('getFileList()', () => {
-      it('sends to gitFs', async () => {
-        await initRepoMock();
-        const branchExists = await bitbucket.branchExists('test');
-        expect(branchExists).toEqual(true);
-        expect(httpMock.getTrace()).toMatchSnapshot();
-      });
-    });
-  });
-
   describe('isBranchStale()', () => {
     it('sends to gitFs', async () => {
       await initRepoMock();
@@ -846,14 +826,6 @@ describe('platform/bitbucket', () => {
     });
   });
 
-  describe('getFile()', () => {
-    it('sends to gitFs', async () => {
-      await initRepoMock();
-      expect(await bitbucket.getFile('test.file')).toMatchSnapshot();
-      expect(httpMock.getTrace()).toMatchSnapshot();
-    });
-  });
-
   describe('getCommitMessages()', () => {
     it('sends to gitFs', async () => {
       await initRepoMock();
diff --git a/lib/platform/bitbucket/index.ts b/lib/platform/bitbucket/index.ts
index 4e12052e5c5863c0b1d6ef149b3c27d55e60a598..0348c5a057d82cfbcfa5969ac45ec3b70f60bdb7 100644
--- a/lib/platform/bitbucket/index.ts
+++ b/lib/platform/bitbucket/index.ts
@@ -177,11 +177,6 @@ export function getRepoForceRebase(): Promise<boolean> {
 
 // Search
 
-// Get full file list
-export function getFileList(): Promise<string[]> {
-  return git.getFileList();
-}
-
 export async function setBaseBranch(
   branchName = config.baseBranch
 ): Promise<string> {
@@ -215,13 +210,6 @@ export function isBranchStale(branchName: string): Promise<boolean> {
   return git.isBranchStale(branchName);
 }
 
-export function getFile(
-  filePath: string,
-  branchName?: string
-): Promise<string> {
-  return git.getFile(filePath, branchName);
-}
-
 // istanbul ignore next
 function matchesState(state: string, desiredState: string): boolean {
   if (desiredState === PR_STATE_ALL) {
diff --git a/lib/platform/common.ts b/lib/platform/common.ts
index 5c13b201834e99cc86c792fa4813317904819c81..32e9df9841b7629fd4d0a76404c02fce6d27c2a3 100644
--- a/lib/platform/common.ts
+++ b/lib/platform/common.ts
@@ -193,7 +193,6 @@ export interface Platform {
   getPrFiles(pr: Pr): Promise<string[]>;
   getAllRenovateBranches(branchPrefix: string): Promise<string[]>;
   ensureIssueClosing(title: string): Promise<void>;
-  getFileList(): Promise<string[]>;
   ensureIssue(
     issueConfig: EnsureIssueConfig
   ): Promise<EnsureIssueResult | null>;
@@ -231,6 +230,5 @@ export interface Platform {
     requiredStatusChecks?: string[] | null
   ): Promise<BranchStatus>;
   getBranchPr(branchName: string): Promise<Pr | null>;
-  getFile(lockFileName: string, branchName?: string): Promise<string | null>;
   initPlatform(config: RenovateConfig): Promise<PlatformConfig>;
 }
diff --git a/lib/platform/gitea/index.spec.ts b/lib/platform/gitea/index.spec.ts
index 91768cd9ad2f8fbaf6bc8e640093ed1a4d96d75f..0df4a2156988814af7b141ebcb292ce17accb849 100644
--- a/lib/platform/gitea/index.spec.ts
+++ b/lib/platform/gitea/index.spec.ts
@@ -1414,25 +1414,6 @@ describe('platform/gitea', () => {
     });
   });
 
-  describe('getFile', () => {
-    it('should propagate call to storage class', async () => {
-      await initFakeRepo();
-      await gitea.getFile('some-file', 'some-branch');
-
-      expect(gitvcs.getFile).toHaveBeenCalledTimes(1);
-      expect(gitvcs.getFile).toHaveBeenCalledWith('some-file', 'some-branch');
-    });
-  });
-
-  describe('getFileList', () => {
-    it('propagates call to storage class', async () => {
-      await initFakeRepo();
-      await gitea.getFileList();
-
-      expect(gitvcs.getFileList).toHaveBeenCalledTimes(1);
-    });
-  });
-
   describe('getAllRenovateBranches', () => {
     it('should propagate call to storage class', async () => {
       await initFakeRepo();
diff --git a/lib/platform/gitea/index.ts b/lib/platform/gitea/index.ts
index 8aebee95c0455a2d55db4e2b4eda3ff8feeedc1f..f28be8edafa1856b43f323e3a696d45104201275 100644
--- a/lib/platform/gitea/index.ts
+++ b/lib/platform/gitea/index.ts
@@ -878,14 +878,6 @@ const platform: Platform = {
     return git.getBranchLastCommitTime(branchName);
   },
 
-  getFile(lockFileName: string, branchName?: string): Promise<string> {
-    return git.getFile(lockFileName, branchName);
-  },
-
-  getFileList(): Promise<string[]> {
-    return git.getFileList();
-  },
-
   getAllRenovateBranches(branchPrefix: string): Promise<string[]> {
     return git.getAllRenovateBranches(branchPrefix);
   },
@@ -919,8 +911,6 @@ export const {
   getBranchStatus,
   getBranchStatusCheck,
   getCommitMessages,
-  getFile,
-  getFileList,
   getIssueList,
   getPr,
   getPrBody,
diff --git a/lib/platform/github/index.ts b/lib/platform/github/index.ts
index 2302bf6f3dde164e17cf510d65770d6cd10a298c..144cbcedad95ae5d29402abeaad82036afcaa936 100644
--- a/lib/platform/github/index.ts
+++ b/lib/platform/github/index.ts
@@ -495,11 +495,6 @@ export function setBranchPrefix(branchPrefix: string): Promise<void> {
 
 // Search
 
-// istanbul ignore next
-export function getFileList(): Promise<string[]> {
-  return git.getFileList();
-}
-
 // Branch
 
 // istanbul ignore next
@@ -519,14 +514,6 @@ export function isBranchStale(branchName: string): Promise<boolean> {
   return git.isBranchStale(branchName);
 }
 
-// istanbul ignore next
-export function getFile(
-  filePath: string,
-  branchName?: string
-): Promise<string> {
-  return git.getFile(filePath, branchName);
-}
-
 // istanbul ignore next
 export function deleteBranch(
   branchName: string,
diff --git a/lib/platform/gitlab/__snapshots__/index.spec.ts.snap b/lib/platform/gitlab/__snapshots__/index.spec.ts.snap
index 6fe7bf60c6e5a3d2a475cac9f5e5e7665e6159a9..49186e996c8b9660c307e7d28b2d782e4a77bf44 100644
--- a/lib/platform/gitlab/__snapshots__/index.spec.ts.snap
+++ b/lib/platform/gitlab/__snapshots__/index.spec.ts.snap
@@ -148,33 +148,6 @@ Array [
 
 exports[`platform/gitlab addReviewers(issueNo, reviewers) should add the given reviewers to the PR 1`] = `Array []`;
 
-exports[`platform/gitlab branchExists() getFileList() sends to gitFs 1`] = `
-Array [
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "host": "gitlab.com",
-      "private-token": "abc123",
-      "user-agent": "https://github.com/renovatebot/renovate",
-    },
-    "method": "GET",
-    "url": "https://gitlab.com/api/v4/projects/some%2Frepo",
-  },
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "host": "gitlab.com",
-      "private-token": "abc123",
-      "user-agent": "https://github.com/renovatebot/renovate",
-    },
-    "method": "GET",
-    "url": "https://gitlab.com/api/v4/user",
-  },
-]
-`;
-
 exports[`platform/gitlab commitFiles() sends to gitFs 1`] = `
 Array [
   Object {
@@ -1492,35 +1465,6 @@ Array [
 
 exports[`platform/gitlab getCommitMessages() passes to git 1`] = `undefined`;
 
-exports[`platform/gitlab getFile() sends to gitFs 1`] = `undefined`;
-
-exports[`platform/gitlab getFileList() sends to gitFs 1`] = `
-Array [
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "host": "gitlab.com",
-      "private-token": "abc123",
-      "user-agent": "https://github.com/renovatebot/renovate",
-    },
-    "method": "GET",
-    "url": "https://gitlab.com/api/v4/projects/some%2Frepo",
-  },
-  Object {
-    "headers": Object {
-      "accept": "application/json",
-      "accept-encoding": "gzip, deflate",
-      "host": "gitlab.com",
-      "private-token": "abc123",
-      "user-agent": "https://github.com/renovatebot/renovate",
-    },
-    "method": "GET",
-    "url": "https://gitlab.com/api/v4/user",
-  },
-]
-`;
-
 exports[`platform/gitlab getPr(prNo) returns the PR 1`] = `
 Object {
   "body": "a merge request",
diff --git a/lib/platform/gitlab/index.spec.ts b/lib/platform/gitlab/index.spec.ts
index 438e1873ff3cb2ef316f0c6388d231ca24f77888..fa323cbbb11a22f36ec2214f1d8a0527828eb518 100644
--- a/lib/platform/gitlab/index.spec.ts
+++ b/lib/platform/gitlab/index.spec.ts
@@ -387,22 +387,6 @@ describe('platform/gitlab', () => {
       expect(httpMock.getTrace()).toMatchSnapshot();
     });
   });
-  describe('getFileList()', () => {
-    it('sends to gitFs', async () => {
-      await initRepo();
-      await gitlab.getFileList();
-      expect(httpMock.getTrace()).toMatchSnapshot();
-    });
-  });
-  describe('branchExists()', () => {
-    describe('getFileList()', () => {
-      it('sends to gitFs', async () => {
-        await initRepo();
-        await gitlab.branchExists('');
-        expect(httpMock.getTrace()).toMatchSnapshot();
-      });
-    });
-  });
   describe('getAllRenovateBranches()', () => {
     it('sends to gitFs', async () => {
       await initRepo();
@@ -1225,12 +1209,6 @@ These updates have all been created already. Click a checkbox below to force a r
       expect(gitlab.getPrBody(prBody)).toMatchSnapshot();
     });
   });
-  describe('getFile()', () => {
-    it('sends to gitFs', async () => {
-      await initRepo();
-      expect(await gitlab.getFile('')).toMatchSnapshot();
-    });
-  });
   describe('commitFiles()', () => {
     it('sends to gitFs', async () => {
       expect.assertions(1);
diff --git a/lib/platform/gitlab/index.ts b/lib/platform/gitlab/index.ts
index 739b43b945affe2d1269abdd17a6d28db9d8ada0..f83527d874c9a3b9b6945468951fd99e48f8a94e 100644
--- a/lib/platform/gitlab/index.ts
+++ b/lib/platform/gitlab/index.ts
@@ -286,13 +286,6 @@ export /* istanbul ignore next */ function setBranchPrefix(
   return git.setBranchPrefix(branchPrefix);
 }
 
-// Search
-
-// Get full file list
-export function getFileList(): Promise<string[]> {
-  return git.getFileList();
-}
-
 // Returns true if branch exists, otherwise false
 export function branchExists(branchName: string): Promise<boolean> {
   return git.branchExists(branchName);
@@ -631,13 +624,6 @@ export function commitFiles(
   return git.commitFiles(commitFilesConfig);
 }
 
-export function getFile(
-  filePath: string,
-  branchName?: string
-): Promise<string> {
-  return git.getFile(filePath, branchName);
-}
-
 export async function deleteBranch(
   branchName: string,
   shouldClosePr = false
diff --git a/lib/workers/branch/get-updated.spec.ts b/lib/workers/branch/get-updated.spec.ts
index 770269fe8b41b971ddb21af0dfa8a1cb4f8fd1c9..70e12e2a885e2f7f1019f8f18fcbb1c97fa11e6d 100644
--- a/lib/workers/branch/get-updated.spec.ts
+++ b/lib/workers/branch/get-updated.spec.ts
@@ -1,4 +1,4 @@
-import { defaultConfig, mocked, platform } from '../../../test/util';
+import { defaultConfig, git, mocked } from '../../../test/util';
 import * as datasourceGitSubmodules from '../../datasource/git-submodules';
 import * as _composer from '../../manager/composer';
 import * as _gitSubmodules from '../../manager/git-submodules';
@@ -15,6 +15,7 @@ const autoReplace = mocked(_autoReplace);
 jest.mock('../../manager/composer');
 jest.mock('../../manager/npm');
 jest.mock('../../manager/git-submodules');
+jest.mock('../../util/git');
 jest.mock('./auto-replace');
 
 describe('workers/branch/get-updated', () => {
@@ -26,7 +27,7 @@ describe('workers/branch/get-updated', () => {
         upgrades: [],
       } as never;
       npm.updateDependency = jest.fn();
-      platform.getFile.mockResolvedValueOnce('existing content');
+      git.getFile.mockResolvedValueOnce('existing content');
     });
     it('handles autoreplace base updated', async () => {
       config.upgrades.push({ manager: 'html', branchName: undefined });
diff --git a/lib/workers/branch/get-updated.ts b/lib/workers/branch/get-updated.ts
index 569dd61af9fdb0a676ff817d3cacea6d32d8519f..3d5f64e37bd9835bb2cfb393b5a994be1eec6fa2 100644
--- a/lib/workers/branch/get-updated.ts
+++ b/lib/workers/branch/get-updated.ts
@@ -4,7 +4,8 @@ import * as datasourceGitSubmodules from '../../datasource/git-submodules';
 import { logger } from '../../logger';
 import { get } from '../../manager';
 import { ArtifactError } from '../../manager/common';
-import { File, platform } from '../../platform';
+import { File } from '../../platform';
+import { getFile } from '../../util/git';
 import { BranchConfig } from '../common';
 import { doAutoReplace } from './auto-replace';
 
@@ -39,7 +40,7 @@ export async function getUpdatedPackageFiles(
     } else {
       let existingContent = updatedFileContents[packageFile];
       if (!existingContent) {
-        existingContent = await platform.getFile(
+        existingContent = await getFile(
           packageFile,
           reuseExistingBranch ? config.branchName : config.baseBranch
         );
@@ -160,7 +161,7 @@ export async function getUpdatedPackageFiles(
       if (updateArtifacts) {
         const packageFileContents =
           updatedFileContents[packageFile] ||
-          (await platform.getFile(
+          (await getFile(
             packageFile,
             config.reuseExistingBranch ? config.branchName : config.baseBranch
           ));
diff --git a/lib/workers/branch/lock-files/index.spec.ts b/lib/workers/branch/lock-files/index.spec.ts
index 7f2db89b45c39ff23607c907bac6393644a47510..4637d34e313a84acbd051d7410811494d655b770 100644
--- a/lib/workers/branch/lock-files/index.spec.ts
+++ b/lib/workers/branch/lock-files/index.spec.ts
@@ -1,5 +1,5 @@
 import _fs from 'fs-extra';
-import { mocked } from '../../../../test/util';
+import { git, mocked } from '../../../../test/util';
 import { getConfig } from '../../../config/defaults';
 import { PostUpdateConfig } from '../../../manager/common';
 import * as _lockFiles from '../../../manager/npm/post-update';
@@ -21,6 +21,8 @@ const lerna = mocked(_lerna);
 const hostRules = mocked(_hostRules);
 const platform = mocked(_platform);
 
+jest.mock('../../../util/git');
+
 hostRules.find = jest.fn((_) => ({
   token: 'abc',
 }));
@@ -76,7 +78,7 @@ describe('manager/npm/post-update', () => {
         ...defaultConfig,
         localDir: 'some-tmp-dir',
       };
-      platform.getFile.mockResolvedValueOnce('some lock file contents');
+      git.getFile.mockResolvedValueOnce('some lock file contents');
       npm.generateLockFile = jest.fn();
       npm.generateLockFile.mockResolvedValueOnce({
         lockFile: 'some lock file contents',
diff --git a/lib/workers/pr/code-owners.spec.ts b/lib/workers/pr/code-owners.spec.ts
index 9e24673a0ee8049187e363249db005f50aa38450..c1d8ac782a3d7801ed4b0cf2929b97cdd344491b 100644
--- a/lib/workers/pr/code-owners.spec.ts
+++ b/lib/workers/pr/code-owners.spec.ts
@@ -1,8 +1,10 @@
 import { mock } from 'jest-mock-extended';
-import { platform } from '../../../test/util';
+import { git, platform } from '../../../test/util';
 import { Pr } from '../../platform';
 import { codeOwnersForPr } from './code-owners';
 
+jest.mock('../../util/git');
+
 describe('workers/pr/code-owners', () => {
   describe('codeOwnersForPr', () => {
     let pr: Pr;
@@ -11,13 +13,13 @@ describe('workers/pr/code-owners', () => {
       pr = mock<Pr>();
     });
     it('returns global code owner', async () => {
-      platform.getFile.mockResolvedValueOnce(['* @jimmy'].join('\n'));
+      git.getFile.mockResolvedValueOnce(['* @jimmy'].join('\n'));
       platform.getPrFiles.mockResolvedValueOnce(['README.md']);
       const codeOwners = await codeOwnersForPr(pr);
       expect(codeOwners).toEqual(['@jimmy']);
     });
     it('returns more specific code owners', async () => {
-      platform.getFile.mockResolvedValueOnce(
+      git.getFile.mockResolvedValueOnce(
         ['* @jimmy', 'package.json @john @maria'].join('\n')
       );
       platform.getPrFiles.mockResolvedValueOnce(['package.json']);
@@ -25,7 +27,7 @@ describe('workers/pr/code-owners', () => {
       expect(codeOwners).toEqual(['@john', '@maria']);
     });
     it('ignores comments and leading/trailing whitespace', async () => {
-      platform.getFile.mockResolvedValueOnce(
+      git.getFile.mockResolvedValueOnce(
         [
           '# comment line',
           '    \t    ',
@@ -39,21 +41,19 @@ describe('workers/pr/code-owners', () => {
       expect(codeOwners).toEqual(['@john', '@maria']);
     });
     it('returns empty array when no code owners set', async () => {
-      platform.getFile.mockResolvedValueOnce(null);
+      git.getFile.mockResolvedValueOnce(null);
       platform.getPrFiles.mockResolvedValueOnce(['package.json']);
       const codeOwners = await codeOwnersForPr(pr);
       expect(codeOwners).toEqual([]);
     });
     it('returns empty array when no code owners match', async () => {
-      platform.getFile.mockResolvedValueOnce(
-        ['package-lock.json @mike'].join('\n')
-      );
+      git.getFile.mockResolvedValueOnce(['package-lock.json @mike'].join('\n'));
       platform.getPrFiles.mockResolvedValueOnce(['yarn.lock']);
       const codeOwners = await codeOwnersForPr(pr);
       expect(codeOwners).toEqual([]);
     });
     it('returns empty array when error occurs', async () => {
-      platform.getFile.mockImplementationOnce((_, __) => {
+      git.getFile.mockImplementationOnce((_, __) => {
         throw new Error();
       });
       const codeOwners = await codeOwnersForPr(pr);
@@ -67,7 +67,7 @@ describe('workers/pr/code-owners', () => {
     ];
     codeOwnerFilePaths.forEach((codeOwnerFilePath) => {
       it(`detects code owner file at '${codeOwnerFilePath}'`, async () => {
-        platform.getFile.mockImplementation((path, _) => {
+        git.getFile.mockImplementation((path, _) => {
           if (path === codeOwnerFilePath) {
             return Promise.resolve(['* @mike'].join('\n'));
           }
diff --git a/lib/workers/pr/code-owners.ts b/lib/workers/pr/code-owners.ts
index 1f5090e39d28fde1a7837a873e57ae4b3a9a87f0..5945b9cc8d9d185bcae3f44b40074d7b795aa2d5 100644
--- a/lib/workers/pr/code-owners.ts
+++ b/lib/workers/pr/code-owners.ts
@@ -1,14 +1,15 @@
 import ignore from 'ignore';
 import { logger } from '../../logger';
 import { Pr, platform } from '../../platform';
+import { getFile } from '../../util/git';
 
 export async function codeOwnersForPr(pr: Pr): Promise<string[]> {
   try {
     const codeOwnersFile =
-      (await platform.getFile('CODEOWNERS', pr.targetBranch)) ||
-      (await platform.getFile('.github/CODEOWNERS', pr.targetBranch)) ||
-      (await platform.getFile('.gitlab/CODEOWNERS', pr.targetBranch)) ||
-      (await platform.getFile('docs/CODEOWNERS', pr.targetBranch));
+      (await getFile('CODEOWNERS', pr.targetBranch)) ||
+      (await getFile('.github/CODEOWNERS', pr.targetBranch)) ||
+      (await getFile('.gitlab/CODEOWNERS', pr.targetBranch)) ||
+      (await getFile('docs/CODEOWNERS', pr.targetBranch));
 
     if (!codeOwnersFile) {
       return [];
diff --git a/lib/workers/repository/extract/file-match.spec.ts b/lib/workers/repository/extract/file-match.spec.ts
index d4d8424d687a587b03a60ab7f68310a1ddbdcb48..cef8ce0b55f616f31ec865801cb7062301f24360 100644
--- a/lib/workers/repository/extract/file-match.spec.ts
+++ b/lib/workers/repository/extract/file-match.spec.ts
@@ -1,6 +1,8 @@
-import { RenovateConfig, platform } from '../../../../test/util';
+import { RenovateConfig, git } from '../../../../test/util';
 import * as fileMatch from './file-match';
 
+jest.mock('../../../util/git');
+
 describe('workers/repository/extract/file-match', () => {
   const fileList = ['package.json', 'frontend/package.json'];
   describe('getIncludedFiles()', () => {
@@ -47,14 +49,14 @@ describe('workers/repository/extract/file-match', () => {
       fileMatch: ['(^|/)package.json$'],
     };
     it('returns npm files', async () => {
-      platform.getFileList.mockResolvedValue(fileList);
+      git.getFileList.mockResolvedValue(fileList);
       fileList.push('Dockerfile');
       const res = await fileMatch.getMatchingFiles(config);
       expect(res).toMatchSnapshot();
       expect(res).toHaveLength(2);
     });
     it('deduplicates', async () => {
-      platform.getFileList.mockResolvedValue(fileList);
+      git.getFileList.mockResolvedValue(fileList);
       config.fileMatch.push('package.json');
       const res = await fileMatch.getMatchingFiles(config);
       expect(res).toMatchSnapshot();
diff --git a/lib/workers/repository/extract/file-match.ts b/lib/workers/repository/extract/file-match.ts
index b07a08994ecb9da78af4a3c4ed52cebdbb0debfb..1f2c37b8406925c3036f7771728bf1f2ef76b97c 100644
--- a/lib/workers/repository/extract/file-match.ts
+++ b/lib/workers/repository/extract/file-match.ts
@@ -1,7 +1,7 @@
 import minimatch from 'minimatch';
 import { RenovateConfig } from '../../../config/common';
 import { logger } from '../../../logger';
-import { platform } from '../../../platform';
+import { getFileList } from '../../../util/git';
 import { regEx } from '../../../util/regex';
 
 export function getIncludedFiles(
@@ -36,10 +36,6 @@ export function filterIgnoredFiles(
   );
 }
 
-export function getFileList(): Promise<string[]> {
-  return platform.getFileList();
-}
-
 export function getFilteredFileList(
   config: RenovateConfig,
   fileList: string[]
diff --git a/lib/workers/repository/extract/index.spec.ts b/lib/workers/repository/extract/index.spec.ts
index 90e5952d9a748a03a83b40577c314ef2df699dde..fdfff9e5164c0c475330cfb3bbaeb07e686747a1 100644
--- a/lib/workers/repository/extract/index.spec.ts
+++ b/lib/workers/repository/extract/index.spec.ts
@@ -1,9 +1,10 @@
-import { defaultConfig, mocked, platform } from '../../../../test/util';
+import { defaultConfig, git, mocked } from '../../../../test/util';
 import { RenovateConfig } from '../../../config';
 import * as _managerFiles from './manager-files';
 import { extractAllDependencies } from '.';
 
 jest.mock('./manager-files');
+jest.mock('../../../util/git');
 
 const managerFiles = mocked(_managerFiles);
 
@@ -13,7 +14,7 @@ describe('workers/repository/extract/index', () => {
     const fileList = ['README', 'package.json', 'tasks/ansible.yaml'];
     beforeEach(() => {
       jest.resetAllMocks();
-      platform.getFileList.mockResolvedValue(fileList);
+      git.getFileList.mockResolvedValue(fileList);
       config = { ...defaultConfig };
     });
     it('runs', async () => {
diff --git a/lib/workers/repository/init/config.spec.ts b/lib/workers/repository/init/config.spec.ts
index 38a3c5e8809cb0240704e383c0861e2ef5a7b4ab..736f65077872e54241dca4b428e40130d6ce4e1d 100644
--- a/lib/workers/repository/init/config.spec.ts
+++ b/lib/workers/repository/init/config.spec.ts
@@ -2,13 +2,14 @@ import {
   RenovateConfig,
   fs,
   getConfig,
+  git,
   mocked,
-  platform,
 } from '../../../../test/util';
 import * as _migrateAndValidate from '../../../config/migrate-validate';
 import { mergeRenovateConfig } from './config';
 
 jest.mock('../../../util/fs');
+jest.mock('../../../util/git');
 
 const migrateAndValidate = mocked(_migrateAndValidate);
 
@@ -31,13 +32,13 @@ describe('workers/repository/init/config', () => {
       });
     });
     it('returns config if not found', async () => {
-      platform.getFileList.mockResolvedValue(['package.json']);
+      git.getFileList.mockResolvedValue(['package.json']);
       fs.readLocalFile.mockResolvedValue('{}');
       const res = await mergeRenovateConfig(config);
       expect(res).toMatchObject(config);
     });
     it('uses package.json config if found', async () => {
-      platform.getFileList.mockResolvedValue(['package.json']);
+      git.getFileList.mockResolvedValue(['package.json']);
       const pJson = JSON.stringify({
         name: 'something',
         renovate: {
@@ -49,7 +50,7 @@ describe('workers/repository/init/config', () => {
       expect(renovateConfig).toBeTruthy();
     });
     it('returns error if cannot parse', async () => {
-      platform.getFileList.mockResolvedValue(['package.json', 'renovate.json']);
+      git.getFileList.mockResolvedValue(['package.json', 'renovate.json']);
       fs.readLocalFile.mockResolvedValue('cannot parse');
       let e;
       try {
@@ -63,7 +64,7 @@ describe('workers/repository/init/config', () => {
       expect(e.validationMessage).toMatchSnapshot();
     });
     it('throws error if duplicate keys', async () => {
-      platform.getFileList.mockResolvedValue(['package.json', '.renovaterc']);
+      git.getFileList.mockResolvedValue(['package.json', '.renovaterc']);
       fs.readLocalFile.mockResolvedValue(
         '{ "enabled": true, "enabled": false }'
       );
@@ -79,10 +80,7 @@ describe('workers/repository/init/config', () => {
       expect(e.validationMessage).toMatchSnapshot();
     });
     it('finds and parse renovate.json5', async () => {
-      platform.getFileList.mockResolvedValue([
-        'package.json',
-        'renovate.json5',
-      ]);
+      git.getFileList.mockResolvedValue(['package.json', 'renovate.json5']);
       fs.readLocalFile.mockResolvedValue(`{
         // this is json5 format
       }`);
@@ -90,7 +88,7 @@ describe('workers/repository/init/config', () => {
       expect(renovateConfig).toBeTruthy();
     });
     it('finds .github/renovate.json', async () => {
-      platform.getFileList.mockResolvedValue([
+      git.getFileList.mockResolvedValue([
         'package.json',
         '.github/renovate.json',
       ]);
@@ -99,7 +97,7 @@ describe('workers/repository/init/config', () => {
       expect(renovateConfig).toBeTruthy();
     });
     it('finds .gitlab/renovate.json', async () => {
-      platform.getFileList.mockResolvedValue([
+      git.getFileList.mockResolvedValue([
         'package.json',
         '.gitlab/renovate.json',
       ]);
@@ -108,19 +106,13 @@ describe('workers/repository/init/config', () => {
       expect(renovateConfig).toBeTruthy();
     });
     it('finds .renovaterc.json', async () => {
-      platform.getFileList.mockResolvedValue([
-        'package.json',
-        '.renovaterc.json',
-      ]);
+      git.getFileList.mockResolvedValue(['package.json', '.renovaterc.json']);
       fs.readLocalFile.mockResolvedValue('{}');
       const renovateConfig = await mergeRenovateConfig(config);
       expect(renovateConfig).toBeTruthy();
     });
     it('throws error if misconfigured', async () => {
-      platform.getFileList.mockResolvedValue([
-        'package.json',
-        '.renovaterc.json',
-      ]);
+      git.getFileList.mockResolvedValue(['package.json', '.renovaterc.json']);
       fs.readLocalFile.mockResolvedValue('{}');
       migrateAndValidate.migrateAndValidate.mockResolvedValueOnce({
         errors: [{ depName: 'dep', message: 'test error' }],
diff --git a/lib/workers/repository/init/config.ts b/lib/workers/repository/init/config.ts
index 68bce6f6bc45990bc5ed6d2c3a107cabb047b1d5..4768afc10cd42a25a5c17734a43e3a4377818eb5 100644
--- a/lib/workers/repository/init/config.ts
+++ b/lib/workers/repository/init/config.ts
@@ -10,11 +10,11 @@ import * as presets from '../../../config/presets';
 import { CONFIG_VALIDATION } from '../../../constants/error-messages';
 import * as npmApi from '../../../datasource/npm';
 import { logger } from '../../../logger';
-import { platform } from '../../../platform';
 import { ExternalHostError } from '../../../types/errors/external-host-error';
 import { getCache } from '../../../util/cache/repository';
 import { clone } from '../../../util/clone';
 import { readLocalFile } from '../../../util/fs';
+import { getFileList } from '../../../util/git';
 import * as hostRules from '../../../util/host-rules';
 import { flattenPackageRules } from './flatten';
 
@@ -23,7 +23,7 @@ export async function mergeRenovateConfig(
   config: RenovateConfig
 ): Promise<RenovateConfig> {
   let returnConfig = { ...config };
-  const fileList = await platform.getFileList();
+  const fileList = await getFileList();
   async function detectConfigFile(): Promise<string | null> {
     for (const fileName of configFileNames) {
       if (fileName === 'package.json') {
diff --git a/lib/workers/repository/onboarding/branch/check.ts b/lib/workers/repository/onboarding/branch/check.ts
index 363c697cec7548f3c84a65069b5f67342b5d95ca..e74f623e000d482afb2ae0f9e25311f75c19a7db 100644
--- a/lib/workers/repository/onboarding/branch/check.ts
+++ b/lib/workers/repository/onboarding/branch/check.ts
@@ -5,10 +5,11 @@ import { PR_STATE_NOT_OPEN } from '../../../../constants/pull-requests';
 import { logger } from '../../../../logger';
 import { platform } from '../../../../platform';
 import { readLocalFile } from '../../../../util/fs';
+import { getFileList } from '../../../../util/git';
 
 const findFile = async (fileName: string): Promise<boolean> => {
   logger.debug(`findFile(${fileName})`);
-  const fileList = await platform.getFileList();
+  const fileList = await getFileList();
   return fileList.includes(fileName);
 };
 
diff --git a/lib/workers/repository/onboarding/branch/index.spec.ts b/lib/workers/repository/onboarding/branch/index.spec.ts
index a9d53d2703ac9eb08b4e4f39a05b77973fef14eb..c7577c4644336804814938af7888a7427236605e 100644
--- a/lib/workers/repository/onboarding/branch/index.spec.ts
+++ b/lib/workers/repository/onboarding/branch/index.spec.ts
@@ -3,6 +3,7 @@ import {
   RenovateConfig,
   fs,
   getConfig,
+  git,
   platform,
 } from '../../../../../test/util';
 import { PR_STATE_OPEN } from '../../../../constants/pull-requests';
@@ -14,6 +15,7 @@ const rebase: any = _rebase;
 
 jest.mock('../../../../workers/repository/onboarding/branch/rebase');
 jest.mock('../../../../util/fs');
+jest.mock('../../../../util/git');
 
 describe('workers/repository/onboarding/branch', () => {
   describe('checkOnboardingBranch', () => {
@@ -21,7 +23,7 @@ describe('workers/repository/onboarding/branch', () => {
     beforeEach(() => {
       jest.resetAllMocks();
       config = getConfig();
-      platform.getFileList.mockResolvedValue([]);
+      git.getFileList.mockResolvedValue([]);
     });
     it('throws if no package files', async () => {
       await expect(checkOnboardingBranch(config)).rejects.toThrow();
@@ -31,7 +33,7 @@ describe('workers/repository/onboarding/branch', () => {
       await expect(checkOnboardingBranch(config)).rejects.toThrow();
     });
     it('has default onboarding config', async () => {
-      platform.getFileList.mockResolvedValue(['package.json']);
+      git.getFileList.mockResolvedValue(['package.json']);
       fs.readLocalFile.mockResolvedValue('{}');
       await checkOnboardingBranch(config);
       expect(
@@ -47,25 +49,25 @@ describe('workers/repository/onboarding/branch', () => {
     it('handles skipped onboarding, requireConfig=true, and a config file', async () => {
       config.requireConfig = true;
       config.onboarding = false;
-      platform.getFileList.mockResolvedValueOnce(['renovate.json']);
+      git.getFileList.mockResolvedValueOnce(['renovate.json']);
       const res = await checkOnboardingBranch(config);
       expect(res.repoIsOnboarded).toBe(true);
     });
     it('handles skipped onboarding, requireConfig=true, and no config file', async () => {
       config.requireConfig = true;
       config.onboarding = false;
-      platform.getFileList.mockResolvedValueOnce(['package.json']);
+      git.getFileList.mockResolvedValueOnce(['package.json']);
       fs.readLocalFile.mockResolvedValueOnce('{}');
       const onboardingResult = checkOnboardingBranch(config);
       await expect(onboardingResult).rejects.toThrow('disabled');
     });
     it('detects repo is onboarded via file', async () => {
-      platform.getFileList.mockResolvedValueOnce(['renovate.json']);
+      git.getFileList.mockResolvedValueOnce(['renovate.json']);
       const res = await checkOnboardingBranch(config);
       expect(res.repoIsOnboarded).toBe(true);
     });
     it('detects repo is onboarded via package.json config', async () => {
-      platform.getFileList.mockResolvedValueOnce(['package.json']);
+      git.getFileList.mockResolvedValueOnce(['package.json']);
       fs.readLocalFile.mockResolvedValueOnce('{"renovate":{}}');
       const res = await checkOnboardingBranch(config);
       expect(res.repoIsOnboarded).toBe(true);
@@ -89,7 +91,7 @@ describe('workers/repository/onboarding/branch', () => {
       await expect(checkOnboardingBranch(config)).rejects.toThrow();
     });
     it('creates onboarding branch with greenkeeper migration', async () => {
-      platform.getFileList.mockResolvedValue(['package.json']);
+      git.getFileList.mockResolvedValue(['package.json']);
       const pJsonContent = JSON.stringify({
         name: 'some-name',
         version: '0.0.1',
@@ -107,7 +109,7 @@ describe('workers/repository/onboarding/branch', () => {
       ).toMatchSnapshot();
     });
     it('updates onboarding branch', async () => {
-      platform.getFileList.mockResolvedValue(['package.json']);
+      git.getFileList.mockResolvedValue(['package.json']);
       platform.findPr.mockResolvedValue(null);
       platform.getBranchPr.mockResolvedValueOnce(mock<Pr>());
       rebase.rebaseOnboardingBranch.mockResolvedValueOnce('abc123');
diff --git a/lib/workers/repository/onboarding/branch/rebase.spec.ts b/lib/workers/repository/onboarding/branch/rebase.spec.ts
index fda34695fac44701f0771a9e75fd404ac87a85a4..9ec32ee7a3dfa1212a1dc8a9f885492ed6bdb687 100644
--- a/lib/workers/repository/onboarding/branch/rebase.spec.ts
+++ b/lib/workers/repository/onboarding/branch/rebase.spec.ts
@@ -2,11 +2,14 @@ import { mock } from 'jest-mock-extended';
 import {
   RenovateConfig,
   defaultConfig,
+  git,
   platform,
 } from '../../../../../test/util';
 import { Pr } from '../../../../platform';
 import { rebaseOnboardingBranch } from './rebase';
 
+jest.mock('../../../../util/git');
+
 describe('workers/repository/onboarding/branch/rebase', () => {
   describe('rebaseOnboardingBranch()', () => {
     let config: RenovateConfig;
@@ -27,7 +30,7 @@ describe('workers/repository/onboarding/branch/rebase', () => {
     it('does nothing if branch is up to date', async () => {
       const contents =
         JSON.stringify(defaultConfig.onboardingConfig, null, 2) + '\n';
-      platform.getFile
+      git.getFile
         .mockResolvedValueOnce(contents) // package.json
         .mockResolvedValueOnce(contents); // renovate.json
       platform.getBranchPr.mockResolvedValueOnce({
diff --git a/lib/workers/repository/onboarding/branch/rebase.ts b/lib/workers/repository/onboarding/branch/rebase.ts
index 445ac440cc0d92effc05d9751778b88e6383a36f..ff4a8e628edbf47a8e5529177b8a8f2016b43dc8 100644
--- a/lib/workers/repository/onboarding/branch/rebase.ts
+++ b/lib/workers/repository/onboarding/branch/rebase.ts
@@ -2,6 +2,7 @@ import { RenovateConfig } from '../../../../config';
 import { configFileNames } from '../../../../config/app-strings';
 import { logger } from '../../../../logger';
 import { platform } from '../../../../platform';
+import { getFile } from '../../../../util/git';
 import { getOnboardingConfig } from './config';
 
 const defaultConfigFile = configFileNames[0];
@@ -31,7 +32,7 @@ export async function rebaseOnboardingBranch(
     logger.debug('Onboarding branch has been edited and cannot be rebased');
     return null;
   }
-  const existingContents = await platform.getFile(
+  const existingContents = await getFile(
     defaultConfigFile,
     config.onboardingBranch
   );