diff --git a/lib/manager/bundler/artifacts.spec.ts b/lib/manager/bundler/artifacts.spec.ts
index 5d0a07c27fa72e61b7775f19a1d66610b160eb1c..6ad0c4b5d6566da6af6c3c9ff1a8e4c2213b3bef 100644
--- a/lib/manager/bundler/artifacts.spec.ts
+++ b/lib/manager/bundler/artifacts.spec.ts
@@ -8,11 +8,11 @@ import { setUtilConfig } from '../../util';
 import { BinarySource } from '../../util/exec/common';
 import * as docker from '../../util/exec/docker';
 import * as _env from '../../util/exec/env';
-import * as _fs from '../../util/fs';
+import * as _gitfs from '../../util/gitfs';
 import * as _bundlerHostRules from './host-rules';
 import { updateArtifacts } from '.';
 
-const fs: jest.Mocked<typeof _fs> = _fs as any;
+const gitfs: jest.Mocked<typeof _gitfs> = _gitfs as any;
 const exec: jest.Mock<typeof _exec> = _exec as any;
 const env = mocked(_env);
 const datasource = mocked(_datasource);
@@ -22,7 +22,7 @@ jest.mock('fs-extra');
 jest.mock('child_process');
 jest.mock('../../../lib/util/exec/env');
 jest.mock('../../../lib/datasource');
-jest.mock('../../../lib/util/fs');
+jest.mock('../../../lib/util/gitfs');
 jest.mock('../../../lib/util/host-rules');
 jest.mock('./host-rules');
 
@@ -59,13 +59,13 @@ describe('bundler.updateArtifacts()', () => {
     ).toBeNull();
   });
   it('returns null if Gemfile.lock was not changed', async () => {
-    fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
-    fs.writeLocalFile.mockResolvedValueOnce(null as never);
+    gitfs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
+    gitfs.writeLocalFile.mockResolvedValueOnce(null as never);
     const execSnapshots = mockExecAll(exec);
     platform.getRepoStatus.mockResolvedValueOnce({
       modified: [],
     } as Git.StatusResult);
-    fs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
+    gitfs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
     expect(
       await updateArtifacts({
         packageFileName: 'Gemfile',
@@ -77,14 +77,14 @@ describe('bundler.updateArtifacts()', () => {
     expect(execSnapshots).toMatchSnapshot();
   });
   it('works for default binarySource', async () => {
-    fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
-    fs.writeLocalFile.mockResolvedValueOnce(null as never);
-    fs.readLocalFile.mockResolvedValueOnce(null);
+    gitfs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
+    gitfs.writeLocalFile.mockResolvedValueOnce(null as never);
+    gitfs.readLocalFile.mockResolvedValueOnce(null);
     const execSnapshots = mockExecAll(exec);
     platform.getRepoStatus.mockResolvedValueOnce({
       modified: ['Gemfile.lock'],
     } as Git.StatusResult);
-    fs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
+    gitfs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
     expect(
       await updateArtifacts({
         packageFileName: 'Gemfile',
@@ -96,14 +96,14 @@ describe('bundler.updateArtifacts()', () => {
     expect(execSnapshots).toMatchSnapshot();
   });
   it('works explicit global binarySource', async () => {
-    fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
-    fs.writeLocalFile.mockResolvedValueOnce(null as never);
-    fs.readLocalFile.mockResolvedValueOnce(null);
+    gitfs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
+    gitfs.writeLocalFile.mockResolvedValueOnce(null as never);
+    gitfs.readLocalFile.mockResolvedValueOnce(null);
     const execSnapshots = mockExecAll(exec);
     platform.getRepoStatus.mockResolvedValueOnce({
       modified: ['Gemfile.lock'],
     } as Git.StatusResult);
-    fs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
+    gitfs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
     expect(
       await updateArtifacts({
         packageFileName: 'Gemfile',
@@ -123,9 +123,9 @@ describe('bundler.updateArtifacts()', () => {
       await setUtilConfig({ ...config, binarySource: BinarySource.Docker });
     });
     it('.ruby-version', async () => {
-      fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
-      fs.writeLocalFile.mockResolvedValueOnce(null as never);
-      fs.readLocalFile.mockResolvedValueOnce('1.2.0');
+      gitfs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
+      gitfs.writeLocalFile.mockResolvedValueOnce(null as never);
+      gitfs.readLocalFile.mockResolvedValueOnce('1.2.0');
       datasource.getPkgReleases.mockResolvedValueOnce({
         releases: [
           { version: '1.0.0' },
@@ -137,7 +137,7 @@ describe('bundler.updateArtifacts()', () => {
       platform.getRepoStatus.mockResolvedValueOnce({
         modified: ['Gemfile.lock'],
       } as Git.StatusResult);
-      fs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
+      gitfs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
       expect(
         await updateArtifacts({
           packageFileName: 'Gemfile',
@@ -152,8 +152,8 @@ describe('bundler.updateArtifacts()', () => {
       expect(execSnapshots).toMatchSnapshot();
     });
     it('compatibility options', async () => {
-      fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
-      fs.writeLocalFile.mockResolvedValueOnce(null as never);
+      gitfs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
+      gitfs.writeLocalFile.mockResolvedValueOnce(null as never);
       datasource.getPkgReleases.mockResolvedValueOnce({
         releases: [
           { version: '1.0.0' },
@@ -165,7 +165,7 @@ describe('bundler.updateArtifacts()', () => {
       platform.getRepoStatus.mockResolvedValueOnce({
         modified: ['Gemfile.lock'],
       } as Git.StatusResult);
-      fs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
+      gitfs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
       expect(
         await updateArtifacts({
           packageFileName: 'Gemfile',
@@ -185,8 +185,8 @@ describe('bundler.updateArtifacts()', () => {
       expect(execSnapshots).toMatchSnapshot();
     });
     it('invalid compatibility options', async () => {
-      fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
-      fs.writeLocalFile.mockResolvedValueOnce(null as never);
+      gitfs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
+      gitfs.writeLocalFile.mockResolvedValueOnce(null as never);
       datasource.getPkgReleases.mockResolvedValueOnce({
         releases: [
           { version: '1.0.0' },
@@ -198,7 +198,7 @@ describe('bundler.updateArtifacts()', () => {
       platform.getRepoStatus.mockResolvedValueOnce({
         modified: ['Gemfile.lock'],
       } as Git.StatusResult);
-      fs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
+      gitfs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
       expect(
         await updateArtifacts({
           packageFileName: 'Gemfile',
@@ -219,9 +219,9 @@ describe('bundler.updateArtifacts()', () => {
     });
 
     it('injects bundler host configuration environment variables', async () => {
-      fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
-      fs.writeLocalFile.mockResolvedValueOnce(null as never);
-      fs.readLocalFile.mockResolvedValueOnce('1.2.0');
+      gitfs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
+      gitfs.writeLocalFile.mockResolvedValueOnce(null as never);
+      gitfs.readLocalFile.mockResolvedValueOnce('1.2.0');
       datasource.getPkgReleases.mockResolvedValueOnce({
         releases: [
           { version: '1.0.0' },
@@ -245,7 +245,7 @@ describe('bundler.updateArtifacts()', () => {
       platform.getRepoStatus.mockResolvedValueOnce({
         modified: ['Gemfile.lock'],
       } as Git.StatusResult);
-      fs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
+      gitfs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
       expect(
         await updateArtifacts({
           packageFileName: 'Gemfile',
@@ -264,8 +264,8 @@ describe('bundler.updateArtifacts()', () => {
     const execError = new Error();
     (execError as any).stdout = ' foo was resolved to';
     (execError as any).stderr = '';
-    fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
-    fs.writeLocalFile.mockResolvedValueOnce(null as never);
+    gitfs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
+    gitfs.writeLocalFile.mockResolvedValueOnce(null as never);
     const execSnapshots = mockExecAll(exec, execError);
     platform.getRepoStatus.mockResolvedValueOnce({
       modified: ['Gemfile.lock'],
@@ -284,13 +284,13 @@ describe('bundler.updateArtifacts()', () => {
     expect(execSnapshots).toMatchSnapshot();
   });
   it('performs lockFileMaintenance', async () => {
-    fs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
-    fs.writeLocalFile.mockResolvedValueOnce(null as never);
+    gitfs.readLocalFile.mockResolvedValueOnce('Current Gemfile.lock');
+    gitfs.writeLocalFile.mockResolvedValueOnce(null as never);
     const execSnapshots = mockExecAll(exec);
     platform.getRepoStatus.mockResolvedValueOnce({
       modified: ['Gemfile.lock'],
     } as Git.StatusResult);
-    fs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
+    gitfs.readLocalFile.mockResolvedValueOnce('Updated Gemfile.lock' as any);
     expect(
       await updateArtifacts({
         packageFileName: 'Gemfile',
diff --git a/lib/manager/bundler/artifacts.ts b/lib/manager/bundler/artifacts.ts
index 661c7f119514b03c2df9f37642c01bd52e4e76e7..780737a0f9920eb03d7679a801328981d9440e1c 100644
--- a/lib/manager/bundler/artifacts.ts
+++ b/lib/manager/bundler/artifacts.ts
@@ -10,7 +10,7 @@ import {
   getSiblingFileName,
   readLocalFile,
   writeLocalFile,
-} from '../../util/fs';
+} from '../../util/gitfs';
 import { isValid } from '../../versioning/ruby';
 import { UpdateArtifact, UpdateArtifactsResult } from '../common';
 import {
diff --git a/lib/manager/bundler/extract.spec.ts b/lib/manager/bundler/extract.spec.ts
index 1f1c86a437009c38e41bb34c53ee7a2c92c775a2..64e1319461dcbb4237e9790b60a09ffeb27c477c 100644
--- a/lib/manager/bundler/extract.spec.ts
+++ b/lib/manager/bundler/extract.spec.ts
@@ -1,11 +1,11 @@
 import { readFileSync } from 'fs';
-import * as _fs from '../../util/fs';
+import * as _gitfs from '../../util/gitfs';
 import { isValid } from '../../versioning/ruby';
 import { extractPackageFile } from './extract';
 
-jest.mock('../../util/fs');
+jest.mock('../../util/gitfs');
 
-const fs: any = _fs;
+const gitfs: any = _gitfs;
 
 const railsGemfile = readFileSync(
   'lib/manager/bundler/__fixtures__/Gemfile.rails',
@@ -74,7 +74,7 @@ describe('lib/manager/bundler/extract', () => {
       expect(await extractPackageFile('nothing here', 'Gemfile')).toBeNull();
     });
     it('parses rails Gemfile', async () => {
-      fs.readLocalFile.mockReturnValueOnce(railsGemfileLock);
+      gitfs.readLocalFile.mockReturnValueOnce(railsGemfileLock);
       const res = await extractPackageFile(railsGemfile, 'Gemfile');
       expect(res).toMatchSnapshot();
       // couple of dependency of ruby rails are not present in the lock file. Filter out those before processing
@@ -98,7 +98,7 @@ describe('lib/manager/bundler/extract', () => {
       validateGems(sourceGroupGemfile, res);
     });
     it('parse webpacker Gemfile', async () => {
-      fs.readLocalFile.mockReturnValueOnce(webPackerGemfileLock);
+      gitfs.readLocalFile.mockReturnValueOnce(webPackerGemfileLock);
       const res = await extractPackageFile(webPackerGemfile, 'Gemfile');
       expect(res).toMatchSnapshot();
       expect(
@@ -112,7 +112,7 @@ describe('lib/manager/bundler/extract', () => {
       validateGems(webPackerGemfile, res);
     });
     it('parse mastodon Gemfile', async () => {
-      fs.readLocalFile.mockReturnValueOnce(mastodonGemfileLock);
+      gitfs.readLocalFile.mockReturnValueOnce(mastodonGemfileLock);
       const res = await extractPackageFile(mastodonGemfile, 'Gemfile');
       expect(res).toMatchSnapshot();
       expect(
@@ -130,7 +130,7 @@ describe('lib/manager/bundler/extract', () => {
       validateGems(mastodonGemfile, res);
     });
     it('parse Ruby CI Gemfile', async () => {
-      fs.readLocalFile.mockReturnValueOnce(rubyCIGemfileLock);
+      gitfs.readLocalFile.mockReturnValueOnce(rubyCIGemfileLock);
       const res = await extractPackageFile(rubyCIGemfile, 'Gemfile');
       expect(res).toMatchSnapshot();
       expect(
@@ -145,7 +145,7 @@ describe('lib/manager/bundler/extract', () => {
     });
   });
   it('parse Gitlab Foss Gemfile', async () => {
-    fs.readLocalFile.mockReturnValueOnce(gitlabFossGemfileLock);
+    gitfs.readLocalFile.mockReturnValueOnce(gitlabFossGemfileLock);
     const res = await extractPackageFile(gitlabFossGemfile, 'Gemfile');
     expect(res).toMatchSnapshot();
     expect(
@@ -160,7 +160,7 @@ describe('lib/manager/bundler/extract', () => {
   });
 
   it('parse source blocks with spaces in Gemfile', async () => {
-    fs.readLocalFile.mockReturnValueOnce(sourceBlockWithNewLinesGemfileLock);
+    gitfs.readLocalFile.mockReturnValueOnce(sourceBlockWithNewLinesGemfileLock);
     const res = await extractPackageFile(
       sourceBlockWithNewLinesGemfile,
       'Gemfile'
diff --git a/lib/manager/bundler/extract.ts b/lib/manager/bundler/extract.ts
index 91096269fb3776317951cdabf88f6a60be4a696a..01ec422d9c628575c7de49c97ede995042c82ec3 100644
--- a/lib/manager/bundler/extract.ts
+++ b/lib/manager/bundler/extract.ts
@@ -1,7 +1,7 @@
 import * as datasourceRubygems from '../../datasource/rubygems';
 import { logger } from '../../logger';
 import { SkipReason } from '../../types';
-import { readLocalFile } from '../../util/fs';
+import { readLocalFile } from '../../util/gitfs';
 import { regEx } from '../../util/regex';
 import { PackageDependency, PackageFile } from '../common';
 import { extractLockFileEntries } from './locked-version';
diff --git a/lib/manager/bundler/utils.ts b/lib/manager/bundler/utils.ts
index 322f5a2af1f25b8ce422c1887c6187955010e8d2..070f9fa516c1ad0e4523e2a52c7fe935b3757fe7 100644
--- a/lib/manager/bundler/utils.ts
+++ b/lib/manager/bundler/utils.ts
@@ -1,6 +1,6 @@
 import { join } from 'upath';
 import { logger } from '../../logger';
-import { ensureDir } from '../../util/fs';
+import { ensureDir } from '../../util/gitfs';
 import { UpdateArtifactsConfig } from '../common';
 
 export async function getGemHome(
diff --git a/lib/manager/cargo/artifacts.ts b/lib/manager/cargo/artifacts.ts
index c94ff14e40329a0b55d69f072d22bc22fc1137e9..0efbc064425cafaeb50a7a312db017c27fd4c59f 100644
--- a/lib/manager/cargo/artifacts.ts
+++ b/lib/manager/cargo/artifacts.ts
@@ -5,7 +5,7 @@ import {
   getSiblingFileName,
   readLocalFile,
   writeLocalFile,
-} from '../../util/fs';
+} from '../../util/gitfs';
 import { UpdateArtifact, UpdateArtifactsResult } from '../common';
 
 export async function updateArtifacts({
diff --git a/lib/manager/cocoapods/artifacts.ts b/lib/manager/cocoapods/artifacts.ts
index 2436c02f383e97f352d3637aeba00e1c73b4a76b..11028be373013bb49d67f7771e594f6d63973ff9 100644
--- a/lib/manager/cocoapods/artifacts.ts
+++ b/lib/manager/cocoapods/artifacts.ts
@@ -7,7 +7,7 @@ import {
   getSiblingFileName,
   readLocalFile,
   writeLocalFile,
-} from '../../util/fs';
+} from '../../util/gitfs';
 import { UpdateArtifact, UpdateArtifactsResult } from '../common';
 import { getCocoaPodsHome } from './utils';
 
diff --git a/lib/manager/cocoapods/utils.ts b/lib/manager/cocoapods/utils.ts
index cf2383a9788453055d12f29a1db1f29db4763319..c1f081e4fd3bc12445141d43d62f6682b124a7a0 100644
--- a/lib/manager/cocoapods/utils.ts
+++ b/lib/manager/cocoapods/utils.ts
@@ -1,6 +1,6 @@
 import { join } from 'upath';
 import { logger } from '../../logger';
-import { ensureDir } from '../../util/fs';
+import { ensureDir } from '../../util/gitfs';
 import { UpdateArtifactsConfig } from '../common';
 
 export async function getCocoaPodsHome(
diff --git a/lib/manager/composer/artifacts.spec.ts b/lib/manager/composer/artifacts.spec.ts
index 86bf0bf0a9fed79ab870f4e74f3090ade30c2a4c..60033b5845c38dc53e518af06341c970766179c4 100644
--- a/lib/manager/composer/artifacts.spec.ts
+++ b/lib/manager/composer/artifacts.spec.ts
@@ -7,17 +7,17 @@ import { setUtilConfig } from '../../util';
 import { BinarySource } from '../../util/exec/common';
 import * as docker from '../../util/exec/docker';
 import * as _env from '../../util/exec/env';
-import * as _fs from '../../util/fs';
+import * as _gitfs from '../../util/gitfs';
 import * as composer from './artifacts';
 
 jest.mock('child_process');
 jest.mock('../../util/exec/env');
-jest.mock('../../util/fs');
+jest.mock('../../util/gitfs');
 jest.mock('../../util/host-rules');
 
 const hostRules = require('../../util/host-rules');
 
-const fs: jest.Mocked<typeof _fs> = _fs as any;
+const gitfs: jest.Mocked<typeof _gitfs> = _gitfs as any;
 const exec: jest.Mock<typeof _exec> = _exec as any;
 const env = mocked(_env);
 
@@ -48,9 +48,9 @@ describe('.updateArtifacts()', () => {
     ).toBeNull();
   });
   it('returns null if unchanged', async () => {
-    fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
+    gitfs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
     const execSnapshots = mockExecAll(exec);
-    fs.readLocalFile.mockReturnValueOnce('Current composer.lock' as any);
+    gitfs.readLocalFile.mockReturnValueOnce('Current composer.lock' as any);
     platform.getRepoStatus.mockResolvedValue({ modified: [] } as StatusResult);
     expect(
       await composer.updateArtifacts({
@@ -63,9 +63,9 @@ describe('.updateArtifacts()', () => {
     expect(execSnapshots).toMatchSnapshot();
   });
   it('uses hostRules to write auth.json', async () => {
-    fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
+    gitfs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
     const execSnapshots = mockExecAll(exec);
-    fs.readLocalFile.mockReturnValueOnce('Current composer.lock' as any);
+    gitfs.readLocalFile.mockReturnValueOnce('Current composer.lock' as any);
     const authConfig = {
       ...config,
       registryUrls: ['https://packagist.renovatebot.com'],
@@ -86,9 +86,9 @@ describe('.updateArtifacts()', () => {
     expect(execSnapshots).toMatchSnapshot();
   });
   it('returns updated composer.lock', async () => {
-    fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
+    gitfs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
     const execSnapshots = mockExecAll(exec);
-    fs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
+    gitfs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
     platform.getRepoStatus.mockResolvedValue({
       modified: ['composer.lock'],
     } as StatusResult);
@@ -103,9 +103,9 @@ describe('.updateArtifacts()', () => {
     expect(execSnapshots).toMatchSnapshot();
   });
   it('performs lockFileMaintenance', async () => {
-    fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
+    gitfs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
     const execSnapshots = mockExecAll(exec);
-    fs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
+    gitfs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
     platform.getRepoStatus.mockResolvedValue({
       modified: ['composer.lock'],
     } as StatusResult);
@@ -125,11 +125,11 @@ describe('.updateArtifacts()', () => {
   it('supports docker mode', async () => {
     jest.spyOn(docker, 'removeDanglingContainers').mockResolvedValueOnce();
     await setUtilConfig({ ...config, binarySource: BinarySource.Docker });
-    fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
+    gitfs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
 
     const execSnapshots = mockExecAll(exec);
 
-    fs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
+    gitfs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
     expect(
       await composer.updateArtifacts({
         packageFileName: 'composer.json',
@@ -141,9 +141,9 @@ describe('.updateArtifacts()', () => {
     expect(execSnapshots).toMatchSnapshot();
   });
   it('supports global mode', async () => {
-    fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
+    gitfs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
     const execSnapshots = mockExecAll(exec);
-    fs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
+    gitfs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
     expect(
       await composer.updateArtifacts({
         packageFileName: 'composer.json',
@@ -158,8 +158,8 @@ describe('.updateArtifacts()', () => {
     expect(execSnapshots).toMatchSnapshot();
   });
   it('catches errors', async () => {
-    fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
-    fs.writeLocalFile.mockImplementationOnce(() => {
+    gitfs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
+    gitfs.writeLocalFile.mockImplementationOnce(() => {
       throw new Error('not found');
     });
     expect(
@@ -172,8 +172,8 @@ describe('.updateArtifacts()', () => {
     ).toMatchSnapshot();
   });
   it('catches unmet requirements errors', async () => {
-    fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
-    fs.writeLocalFile.mockImplementationOnce(() => {
+    gitfs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
+    gitfs.writeLocalFile.mockImplementationOnce(() => {
       throw new Error(
         'fooYour requirements could not be resolved to an installable set of packages.bar'
       );
@@ -188,8 +188,8 @@ describe('.updateArtifacts()', () => {
     ).toMatchSnapshot();
   });
   it('throws for disk space', async () => {
-    fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
-    fs.writeLocalFile.mockImplementationOnce(() => {
+    gitfs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
+    gitfs.writeLocalFile.mockImplementationOnce(() => {
       throw new Error(
         'vendor/composer/07fe2366/sebastianbergmann-php-code-coverage-c896779/src/Report/Html/Renderer/Template/js/d3.min.js:  write error (disk full?).  Continue? (y/n/^C) '
       );
@@ -204,9 +204,9 @@ describe('.updateArtifacts()', () => {
     ).rejects.toThrow();
   });
   it('disables ignorePlatformReqs', async () => {
-    fs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
+    gitfs.readLocalFile.mockResolvedValueOnce('Current composer.lock' as any);
     const execSnapshots = mockExecAll(exec);
-    fs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
+    gitfs.readLocalFile.mockReturnValueOnce('New composer.lock' as any);
     platform.getRepoStatus.mockResolvedValue({
       modified: ['composer.lock'],
     } as StatusResult);
diff --git a/lib/manager/composer/artifacts.ts b/lib/manager/composer/artifacts.ts
index 1b1ad2286f9636068109c192210d1cd625a666f3..557e51f63db1247b8042fecec6e8727fe6f63915 100644
--- a/lib/manager/composer/artifacts.ts
+++ b/lib/manager/composer/artifacts.ts
@@ -18,7 +18,7 @@ import {
   getSiblingFileName,
   readLocalFile,
   writeLocalFile,
-} from '../../util/fs';
+} from '../../util/gitfs';
 import * as hostRules from '../../util/host-rules';
 import { UpdateArtifact, UpdateArtifactsResult } from '../common';
 
diff --git a/lib/manager/composer/extract.spec.ts b/lib/manager/composer/extract.spec.ts
index 52565c2bc90e7b91968ba924ffe8d13010e0e39c..701aede97679a4cb24418852065170e481a5c620 100644
--- a/lib/manager/composer/extract.spec.ts
+++ b/lib/manager/composer/extract.spec.ts
@@ -1,10 +1,10 @@
 import { readFileSync } from 'fs';
-import * as _fs from '../../util/fs';
+import * as _gitfs from '../../util/gitfs';
 import { extractPackageFile } from './extract';
 
-jest.mock('../../util/fs');
+jest.mock('../../util/gitfs');
 
-const fs: any = _fs;
+const gitfs: any = _gitfs;
 
 const requirements1 = readFileSync(
   'lib/manager/composer/__fixtures__/composer1.json',
@@ -63,13 +63,13 @@ describe('lib/manager/composer/extract', () => {
       expect(res.registryUrls).toHaveLength(2);
     });
     it('extracts object repositories and registryUrls with lock file', async () => {
-      fs.readLocalFile.mockResolvedValue(requirements5Lock);
+      gitfs.readLocalFile.mockResolvedValue(requirements5Lock);
       const res = await extractPackageFile(requirements5, packageFile);
       expect(res).toMatchSnapshot();
       expect(res.registryUrls).toHaveLength(2);
     });
     it('extracts dependencies with lock file', async () => {
-      fs.readLocalFile.mockResolvedValue('some content');
+      gitfs.readLocalFile.mockResolvedValue('some content');
       const res = await extractPackageFile(requirements1, packageFile);
       expect(res).toMatchSnapshot();
     });
diff --git a/lib/manager/composer/extract.ts b/lib/manager/composer/extract.ts
index 1a53277532d68dca7f0bc338726436046217aa06..fbe806e7953b2ea67dc3db1449987df363e96e2b 100644
--- a/lib/manager/composer/extract.ts
+++ b/lib/manager/composer/extract.ts
@@ -3,7 +3,7 @@ import * as datasourceGitTags from '../../datasource/git-tags';
 import * as datasourcePackagist from '../../datasource/packagist';
 import { logger } from '../../logger';
 import { SkipReason } from '../../types';
-import { readLocalFile } from '../../util/fs';
+import { readLocalFile } from '../../util/gitfs';
 import { api as semverComposer } from '../../versioning/composer';
 import { PackageDependency, PackageFile } from '../common';
 
diff --git a/lib/manager/gomod/artifacts.ts b/lib/manager/gomod/artifacts.ts
index 48f219aba92abf665ed95cda280c412b7b7babe5..24c37169233809a246902d284af4a2f96cd18ac9 100644
--- a/lib/manager/gomod/artifacts.ts
+++ b/lib/manager/gomod/artifacts.ts
@@ -6,7 +6,7 @@ import { logger } from '../../logger';
 import { platform } from '../../platform';
 import { ExecOptions, exec } from '../../util/exec';
 import { BinarySource } from '../../util/exec/common';
-import { readLocalFile, writeLocalFile } from '../../util/fs';
+import { readLocalFile, writeLocalFile } from '../../util/gitfs';
 import { find } from '../../util/host-rules';
 import { UpdateArtifact, UpdateArtifactsResult } from '../common';
 
diff --git a/lib/manager/gradle-wrapper/artifacts.spec.ts b/lib/manager/gradle-wrapper/artifacts.spec.ts
index d343734a36e4ce0fca30184fc313ba11872bd780..1cbcef6df54469fe92c05f873fddf1a53f63a83c 100644
--- a/lib/manager/gradle-wrapper/artifacts.spec.ts
+++ b/lib/manager/gradle-wrapper/artifacts.spec.ts
@@ -8,8 +8,8 @@ import * as httpMock from '../../../test/httpMock';
 import {
   addReplacingSerializer,
   env,
-  fs,
   getName,
+  gitfs,
   partial,
   platform,
 } from '../../../test/util';
@@ -19,7 +19,7 @@ import { resetPrefetchedImages } from '../../util/exec/docker';
 import * as dcUpdate from '.';
 
 jest.mock('child_process');
-jest.mock('../../util/fs');
+jest.mock('../../util/gitfs');
 jest.mock('../../util/exec/env');
 
 const exec: jest.Mock<typeof _exec> = _exec as any;
@@ -51,7 +51,7 @@ describe(getName(__filename), () => {
     await setUtilConfig(config);
     resetPrefetchedImages();
 
-    fs.readLocalFile.mockResolvedValue('test');
+    gitfs.readLocalFile.mockResolvedValue('test');
   });
 
   afterEach(() => {
diff --git a/lib/manager/gradle-wrapper/artifacts.ts b/lib/manager/gradle-wrapper/artifacts.ts
index dc020ce7e44a69e46af5250a554042404969b8ce..f20fb0d6414bb10c011c988266c3cf9092d0f06f 100644
--- a/lib/manager/gradle-wrapper/artifacts.ts
+++ b/lib/manager/gradle-wrapper/artifacts.ts
@@ -4,7 +4,7 @@ import Git from 'simple-git/promise';
 import { logger } from '../../logger';
 import { platform } from '../../platform';
 import { ExecOptions, exec } from '../../util/exec';
-import { readLocalFile, writeLocalFile } from '../../util/fs';
+import { readLocalFile, writeLocalFile } from '../../util/gitfs';
 import { Http } from '../../util/http';
 import { UpdateArtifact, UpdateArtifactsResult } from '../common';
 import { gradleWrapperFileName, prepareGradleCommand } from '../gradle/index';
diff --git a/lib/manager/gradle/index.spec.ts b/lib/manager/gradle/index.spec.ts
index 5d9e863592606395698d9c4ad086a32e93fcfaf1..8108888d7c8b73841185c0a1a853cec8b1f9d20b 100644
--- a/lib/manager/gradle/index.spec.ts
+++ b/lib/manager/gradle/index.spec.ts
@@ -9,7 +9,7 @@ import * as _util from '../../util';
 import { BinarySource } from '../../util/exec/common';
 import * as _docker from '../../util/exec/docker';
 import * as _env from '../../util/exec/env';
-import * as _utilfs from '../../util/fs';
+import * as _utilfs from '../../util/gitfs';
 import { ExtractConfig } from '../common';
 import { ifSystemSupportsGradle } from './__testutil__/gradle';
 import { GRADLE_DEPENDENCY_REPORT_FILENAME } from './gradle-updates-report';
@@ -44,16 +44,16 @@ async function setupMocks() {
 
   jest.mock('child_process');
   jest.mock('../../util/exec/env');
-  jest.mock('../../util/fs');
+  jest.mock('../../util/gitfs');
   jest.mock('os');
 
   const os: jest.Mocked<typeof _os> = require('os');
-  const utilfs: jest.Mocked<typeof _utilfs> = require('../../util/fs');
+  const gitfs: jest.Mocked<typeof _utilfs> = require('../../util/gitfs');
   const env: jest.Mocked<typeof _env> = require('../../util/exec/env');
   const exec: jest.Mock<typeof _exec> = require('child_process').exec;
   const util: jest.Mocked<typeof _util> = require('../../util');
 
-  utilfs.readLocalFile.mockResolvedValue(`
+  gitfs.readLocalFile.mockResolvedValue(`
     dependency 'foo:foo:1.2.3'
     dependency "bar:bar:3.4.5"
   `);
diff --git a/lib/manager/gradle/index.ts b/lib/manager/gradle/index.ts
index 2af2a8e97e54927eebfa317217bb2547641b1572..06613990dd52eba3afcfb58c49fe78c40db90f85 100644
--- a/lib/manager/gradle/index.ts
+++ b/lib/manager/gradle/index.ts
@@ -8,7 +8,7 @@ import { logger } from '../../logger';
 import { ExternalHostError } from '../../types/errors/external-host-error';
 import { ExecOptions, exec } from '../../util/exec';
 import { BinarySource } from '../../util/exec/common';
-import { readLocalFile } from '../../util/fs';
+import { readLocalFile } from '../../util/gitfs';
 import * as gradleVersioning from '../../versioning/gradle';
 import {
   ExtractConfig,
diff --git a/lib/manager/helm-requirements/extract.spec.ts b/lib/manager/helm-requirements/extract.spec.ts
index 893c4583f229134893879011fa279862db98e507..f73bc6be7f170d332b206ccbf2415c09faec030f 100644
--- a/lib/manager/helm-requirements/extract.spec.ts
+++ b/lib/manager/helm-requirements/extract.spec.ts
@@ -1,16 +1,18 @@
-import * as _fs from '../../util/fs';
+import * as _gitfs from '../../util/gitfs';
 import { extractPackageFile } from './extract';
 
-const fs: any = _fs;
+jest.mock('../../util/gitfs');
+
+const gitfs: any = _gitfs;
 
 describe('lib/manager/helm-requirements/extract', () => {
   describe('extractPackageFile()', () => {
     beforeEach(() => {
       jest.resetAllMocks();
-      fs.readLocalFile = jest.fn();
+      gitfs.readLocalFile = jest.fn();
     });
     it('skips invalid registry urls', async () => {
-      fs.readLocalFile.mockResolvedValueOnce(`
+      gitfs.readLocalFile.mockResolvedValueOnce(`
       apiVersion: v1
       appVersion: "1.0"
       description: A Helm chart for Kubernetes
@@ -39,7 +41,7 @@ describe('lib/manager/helm-requirements/extract', () => {
       expect(result.deps.every((dep) => dep.skipReason)).toEqual(true);
     });
     it('parses simple requirements.yaml correctly', async () => {
-      fs.readLocalFile.mockResolvedValueOnce(`
+      gitfs.readLocalFile.mockResolvedValueOnce(`
       apiVersion: v1
       appVersion: "1.0"
       description: A Helm chart for Kubernetes
@@ -65,7 +67,7 @@ describe('lib/manager/helm-requirements/extract', () => {
       expect(result).toMatchSnapshot();
     });
     it('parses simple requirements.yaml but skips if necessary fields missing', async () => {
-      fs.readLocalFile.mockResolvedValueOnce(`
+      gitfs.readLocalFile.mockResolvedValueOnce(`
       apiVersion: v1
       appVersion: "1.0"
       description: A Helm chart for Kubernetes
@@ -80,7 +82,7 @@ describe('lib/manager/helm-requirements/extract', () => {
       expect(result).toBeNull();
     });
     it('resolves aliased registry urls', async () => {
-      fs.readLocalFile.mockResolvedValueOnce(`
+      gitfs.readLocalFile.mockResolvedValueOnce(`
       apiVersion: v1
       appVersion: "1.0"
       description: A Helm chart for Kubernetes
@@ -104,7 +106,7 @@ describe('lib/manager/helm-requirements/extract', () => {
       expect(result.deps.every((dep) => dep.skipReason)).toEqual(false);
     });
     it("doesn't fail if Chart.yaml is invalid", async () => {
-      fs.readLocalFile.mockResolvedValueOnce(`
+      gitfs.readLocalFile.mockResolvedValueOnce(`
       Invalid Chart.yaml content.
       arr:
       [
@@ -127,7 +129,7 @@ describe('lib/manager/helm-requirements/extract', () => {
       expect(result).toBeNull();
     });
     it('skips local dependencies', async () => {
-      fs.readLocalFile.mockResolvedValueOnce(`
+      gitfs.readLocalFile.mockResolvedValueOnce(`
       apiVersion: v1
       appVersion: "1.0"
       description: A Helm chart for Kubernetes
@@ -153,7 +155,7 @@ describe('lib/manager/helm-requirements/extract', () => {
       expect(result).toMatchSnapshot();
     });
     it('returns null if no dependencies', async () => {
-      fs.readLocalFile.mockResolvedValueOnce(`
+      gitfs.readLocalFile.mockResolvedValueOnce(`
       apiVersion: v1
       appVersion: "1.0"
       description: A Helm chart for Kubernetes
@@ -172,7 +174,7 @@ describe('lib/manager/helm-requirements/extract', () => {
       expect(result).toBeNull();
     });
     it('returns null if requirements.yaml is invalid', async () => {
-      fs.readLocalFile.mockResolvedValueOnce(`
+      gitfs.readLocalFile.mockResolvedValueOnce(`
       apiVersion: v1
       appVersion: "1.0"
       description: A Helm chart for Kubernetes
diff --git a/lib/manager/helm-requirements/extract.ts b/lib/manager/helm-requirements/extract.ts
index ad3b0472a5668eb2818c22e2c0c3061aaf0ab7cd..7f9105e7c2863194d77c7ec7310e59dbfd65047a 100644
--- a/lib/manager/helm-requirements/extract.ts
+++ b/lib/manager/helm-requirements/extract.ts
@@ -3,7 +3,7 @@ import yaml from 'js-yaml';
 import * as datasourceHelm from '../../datasource/helm';
 import { logger } from '../../logger';
 import { SkipReason } from '../../types';
-import { getSiblingFileName, readLocalFile } from '../../util/fs';
+import { getSiblingFileName, readLocalFile } from '../../util/gitfs';
 import { ExtractConfig, PackageDependency, PackageFile } from '../common';
 
 export async function extractPackageFile(
diff --git a/lib/manager/maven/extract.ts b/lib/manager/maven/extract.ts
index f10dda6210330859efe45a1709c760492bb62b2a..948ae5022f5175eca6c6e196d4a20d97d8a7e030 100644
--- a/lib/manager/maven/extract.ts
+++ b/lib/manager/maven/extract.ts
@@ -5,7 +5,7 @@ import * as datasourceMaven from '../../datasource/maven';
 import { MAVEN_REPO } from '../../datasource/maven/common';
 import { logger } from '../../logger';
 import { SkipReason } from '../../types';
-import { readLocalFile } from '../../util/fs';
+import { readLocalFile } from '../../util/gitfs';
 import { ExtractConfig, PackageDependency, PackageFile } from '../common';
 
 export function parsePom(raw: string): XmlDocument | null {
diff --git a/lib/manager/maven/index.spec.ts b/lib/manager/maven/index.spec.ts
index 6fcaf469b88d844eee1ed6fb180ef74f0d2ef28a..2f0487dfab5abb3622c225e4b3ab0ed43212f8b5 100644
--- a/lib/manager/maven/index.spec.ts
+++ b/lib/manager/maven/index.spec.ts
@@ -1,12 +1,12 @@
 import { readFileSync } from 'fs';
-import * as _fs from '../../util/fs';
+import * as _gitfs from '../../util/gitfs';
 import { PackageDependency, PackageFile } from '../common';
 import { extractPackage, resolveParents } from './extract';
 import { extractAllPackageFiles, updateDependency } from './index';
 
-jest.mock('../../util/fs');
+jest.mock('../../util/gitfs');
 
-const fs: any = _fs;
+const gitfs: any = _gitfs;
 
 const pomContent = readFileSync(
   'lib/manager/maven/__fixtures__/simple.pom.xml',
@@ -32,19 +32,19 @@ function selectDep(deps: PackageDependency[], name = 'org.example:quuz') {
 describe('manager/maven', () => {
   describe('extractAllPackageFiles', () => {
     it('should return empty if package has no content', async () => {
-      fs.readLocalFile.mockReturnValueOnce(null);
+      gitfs.readLocalFile.mockReturnValueOnce(null);
       const res = await extractAllPackageFiles({}, ['random.pom.xml']);
       expect(res).toEqual([]);
     });
 
     it('should return empty for packages with invalid content', async () => {
-      fs.readLocalFile.mockReturnValueOnce('invalid content');
+      gitfs.readLocalFile.mockReturnValueOnce('invalid content');
       const res = await extractAllPackageFiles({}, ['random.pom.xml']);
       expect(res).toEqual([]);
     });
 
     it('should return package files info', async () => {
-      fs.readLocalFile.mockReturnValueOnce(pomContent);
+      gitfs.readLocalFile.mockReturnValueOnce(pomContent);
       const packages = await extractAllPackageFiles({}, ['random.pom.xml']);
       // windows path fix
       for (const p of packages) {
@@ -99,7 +99,7 @@ describe('manager/maven', () => {
     });
 
     it('should include registryUrls from parent pom files', async () => {
-      fs.readLocalFile
+      gitfs.readLocalFile
         .mockReturnValueOnce(pomParent)
         .mockReturnValueOnce(pomChild);
       const packages = await extractAllPackageFiles({}, [
@@ -134,7 +134,7 @@ describe('manager/maven', () => {
     });
 
     it('should update to version of the latest dep in implicit group', async () => {
-      fs.readLocalFile.mockReturnValueOnce(origContent);
+      gitfs.readLocalFile.mockReturnValueOnce(origContent);
       const [{ deps }] = await extractAllPackageFiles({}, ['pom.xml']);
 
       const dep1 = selectDep(deps, 'org.example:foo-1');
@@ -179,7 +179,7 @@ describe('manager/maven', () => {
     });
 
     it('should return null for ungrouped deps if content was updated outside', async () => {
-      fs.readLocalFile.mockReturnValueOnce(origContent);
+      gitfs.readLocalFile.mockReturnValueOnce(origContent);
       const [{ deps }] = await extractAllPackageFiles({}, ['pom.xml']);
       const dep = selectDep(deps, 'org.example:bar');
       const upgrade = { ...dep, newValue: '2.0.2' };
diff --git a/lib/manager/mix/artifacts.ts b/lib/manager/mix/artifacts.ts
index c037f01da1896f18f5fac16c3331baf22b96a799..cb5972c91b3d24d3ff6e89bb3046a7bfce29338a 100644
--- a/lib/manager/mix/artifacts.ts
+++ b/lib/manager/mix/artifacts.ts
@@ -4,7 +4,7 @@ import upath from 'upath';
 import { logger } from '../../logger';
 import { exec } from '../../util/exec';
 import { BinarySource } from '../../util/exec/common';
-import { readLocalFile } from '../../util/fs';
+import { readLocalFile } from '../../util/gitfs';
 import { UpdateArtifact, UpdateArtifactsResult } from '../common';
 
 export async function updateArtifacts({
diff --git a/lib/manager/npm/extract/index.spec.ts b/lib/manager/npm/extract/index.spec.ts
index 1afa441d944716be44fff7f42a241a3be66440f6..7cb181416ea5a1348f126d75b3b90319ee64546d 100644
--- a/lib/manager/npm/extract/index.spec.ts
+++ b/lib/manager/npm/extract/index.spec.ts
@@ -1,10 +1,10 @@
 import fs from 'fs';
 import path from 'path';
 import { getConfig } from '../../../config/defaults';
-import * as _fs from '../../../util/fs';
+import * as _gitfs from '../../../util/gitfs/fs';
 import * as npmExtract from '.';
 
-const utilfs: any = _fs;
+const gitfs: any = _gitfs;
 
 // TODO: fix types
 const defaultConfig = getConfig();
@@ -25,7 +25,7 @@ const invalidNameContent = readFixture('invalid-name.json');
 describe('manager/npm/extract', () => {
   describe('.extractPackageFile()', () => {
     beforeEach(() => {
-      utilfs.readLocalFile = jest.fn(() => null);
+      gitfs.readLocalFile = jest.fn(() => null);
     });
     it('returns null if cannot parse', async () => {
       const res = await npmExtract.extractPackageFile(
@@ -85,7 +85,7 @@ describe('manager/npm/extract', () => {
       expect(res).toMatchSnapshot();
     });
     it('finds a lock file', async () => {
-      utilfs.readLocalFile = jest.fn((fileName) => {
+      gitfs.readLocalFile = jest.fn((fileName) => {
         if (fileName === 'yarn.lock') {
           return '# yarn.lock';
         }
@@ -99,7 +99,7 @@ describe('manager/npm/extract', () => {
       expect(res).toMatchSnapshot();
     });
     it('finds and filters .npmrc', async () => {
-      utilfs.readLocalFile = jest.fn((fileName) => {
+      gitfs.readLocalFile = jest.fn((fileName) => {
         if (fileName === '.npmrc') {
           return 'save-exact = true\npackage-lock = false\n';
         }
@@ -113,7 +113,7 @@ describe('manager/npm/extract', () => {
       expect(res.npmrc).toBeDefined();
     });
     it('finds and discards .npmrc', async () => {
-      utilfs.readLocalFile = jest.fn((fileName) => {
+      gitfs.readLocalFile = jest.fn((fileName) => {
         if (fileName === '.npmrc') {
           // eslint-disable-next-line
           return '//registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}\n';
@@ -128,7 +128,7 @@ describe('manager/npm/extract', () => {
       expect(res.npmrc).toBeUndefined();
     });
     it('finds lerna', async () => {
-      utilfs.readLocalFile = jest.fn((fileName) => {
+      gitfs.readLocalFile = jest.fn((fileName) => {
         if (fileName === 'lerna.json') {
           return '{}';
         }
@@ -142,7 +142,7 @@ describe('manager/npm/extract', () => {
       expect(res).toMatchSnapshot();
     });
     it('finds "npmClient":"npm" in lerna.json', async () => {
-      utilfs.readLocalFile = jest.fn((fileName) => {
+      gitfs.readLocalFile = jest.fn((fileName) => {
         if (fileName === 'lerna.json') {
           return '{ "npmClient": "npm" }';
         }
@@ -156,7 +156,7 @@ describe('manager/npm/extract', () => {
       expect(res).toMatchSnapshot();
     });
     it('finds "npmClient":"yarn" in lerna.json', async () => {
-      utilfs.readLocalFile = jest.fn((fileName) => {
+      gitfs.readLocalFile = jest.fn((fileName) => {
         if (fileName === 'lerna.json') {
           return '{ "npmClient": "yarn" }';
         }
@@ -170,7 +170,7 @@ describe('manager/npm/extract', () => {
       expect(res).toMatchSnapshot();
     });
     it('finds simple yarn workspaces', async () => {
-      utilfs.readLocalFile = jest.fn((fileName) => {
+      gitfs.readLocalFile = jest.fn((fileName) => {
         if (fileName === 'lerna.json') {
           return '{}';
         }
@@ -184,7 +184,7 @@ describe('manager/npm/extract', () => {
       expect(res).toMatchSnapshot();
     });
     it('finds complex yarn workspaces', async () => {
-      utilfs.readLocalFile = jest.fn((fileName) => {
+      gitfs.readLocalFile = jest.fn((fileName) => {
         if (fileName === 'lerna.json') {
           return '{}';
         }
diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts
index 514fc773482a70f3d76a933e1ae0839bc19e048b..5142e8c5c35b8e1d7fd46c558eabadc829b0216e 100644
--- a/lib/manager/npm/extract/index.ts
+++ b/lib/manager/npm/extract/index.ts
@@ -10,7 +10,7 @@ import {
   deleteLocalFile,
   getSiblingFileName,
   readLocalFile,
-} from '../../../util/fs';
+} from '../../../util/gitfs';
 import * as nodeVersioning from '../../../versioning/node';
 import { isValid, isVersion } from '../../../versioning/npm';
 import {
diff --git a/lib/manager/npm/extract/npm.spec.ts b/lib/manager/npm/extract/npm.spec.ts
index 69bd2345b1d70a77161eeb43234b25997c6da104..61e399f5e3634e5e4a74f912f7d523c7d9eaa931 100644
--- a/lib/manager/npm/extract/npm.spec.ts
+++ b/lib/manager/npm/extract/npm.spec.ts
@@ -1,15 +1,15 @@
 import { readFileSync } from 'fs';
-import * as _fs from '../../../util/fs';
+import * as _gitfs from '../../../util/gitfs';
 import { getNpmLock } from './npm';
 
-jest.mock('../../../util/fs');
+jest.mock('../../../util/gitfs');
 
-const fs: any = _fs;
+const gitfs: any = _gitfs;
 
 describe('manager/npm/extract/npm', () => {
   describe('.getNpmLock()', () => {
     it('returns empty if failed to parse', async () => {
-      fs.readLocalFile.mockReturnValueOnce('abcd');
+      gitfs.readLocalFile.mockReturnValueOnce('abcd');
       const res = await getNpmLock('package.json');
       expect(Object.keys(res)).toHaveLength(0);
     });
@@ -17,13 +17,13 @@ describe('manager/npm/extract/npm', () => {
       const plocktest1Lock = readFileSync(
         'lib/manager/npm/__fixtures__/plocktest1/package-lock.json'
       );
-      fs.readLocalFile.mockReturnValueOnce(plocktest1Lock);
+      gitfs.readLocalFile.mockReturnValueOnce(plocktest1Lock);
       const res = await getNpmLock('package.json');
       expect(res).toMatchSnapshot();
       expect(Object.keys(res)).toHaveLength(7);
     });
     it('returns empty if no deps', async () => {
-      fs.readLocalFile.mockResolvedValueOnce('{}');
+      gitfs.readLocalFile.mockResolvedValueOnce('{}');
       const res = await getNpmLock('package.json');
       expect(Object.keys(res)).toHaveLength(0);
     });
diff --git a/lib/manager/npm/extract/npm.ts b/lib/manager/npm/extract/npm.ts
index bfabceffa2c0ee85b1eff5f85a544c5b13a11f6f..99da47163c96fd2c57b27c6ffc7f862506dd5c9a 100644
--- a/lib/manager/npm/extract/npm.ts
+++ b/lib/manager/npm/extract/npm.ts
@@ -1,5 +1,5 @@
 import { logger } from '../../../logger';
-import { readLocalFile } from '../../../util/fs';
+import { readLocalFile } from '../../../util/gitfs';
 import { LockFileEntry } from './common';
 
 export async function getNpmLock(
diff --git a/lib/manager/npm/extract/yarn.spec.ts b/lib/manager/npm/extract/yarn.spec.ts
index 05ed6faba5ff33ea71f8277e9ad46585ea2ea0c7..850e8e26b6d3c857ebb8b7008435a66b6029d93b 100644
--- a/lib/manager/npm/extract/yarn.spec.ts
+++ b/lib/manager/npm/extract/yarn.spec.ts
@@ -1,15 +1,15 @@
 import { readFileSync } from 'fs';
-import * as _fs from '../../../util/fs';
+import * as _gitfs from '../../../util/gitfs';
 import { getYarnLock } from './yarn';
 
-jest.mock('../../../util/fs');
+jest.mock('../../../util/gitfs');
 
-const fs: any = _fs;
+const gitfs: any = _gitfs;
 
 describe('manager/npm/extract/yarn', () => {
   describe('.getYarnLock()', () => {
     it('returns empty if exception parsing', async () => {
-      fs.readLocalFile.mockReturnValueOnce('abcd');
+      gitfs.readLocalFile.mockReturnValueOnce('abcd');
       const res = await getYarnLock('package.json');
       expect(Object.keys(res)).toHaveLength(0);
     });
@@ -18,7 +18,7 @@ describe('manager/npm/extract/yarn', () => {
         'lib/manager/npm/__fixtures__/plocktest1/yarn.lock',
         'utf8'
       );
-      fs.readLocalFile.mockReturnValueOnce(plocktest1Lock);
+      gitfs.readLocalFile.mockReturnValueOnce(plocktest1Lock);
       const res = await getYarnLock('package.json');
       expect(res).toMatchSnapshot();
       expect(Object.keys(res)).toHaveLength(7);
diff --git a/lib/manager/npm/extract/yarn.ts b/lib/manager/npm/extract/yarn.ts
index 5af375e6c219061211f109cc6accf57012971697..b40f8636efea86c99e3c2e746e2d2f290c6520c0 100644
--- a/lib/manager/npm/extract/yarn.ts
+++ b/lib/manager/npm/extract/yarn.ts
@@ -1,6 +1,6 @@
 import { parse } from '@yarnpkg/lockfile';
 import { logger } from '../../../logger';
-import { readLocalFile } from '../../../util/fs';
+import { readLocalFile } from '../../../util/gitfs';
 import { LockFileEntry } from './common';
 
 export type YarnLock = Record<string, string>;
diff --git a/lib/manager/npm/post-update/index.ts b/lib/manager/npm/post-update/index.ts
index f380fb289096ca03760291a50f38ded3cb6e811f..86e542d8b55f9715f471708fe44fa47d906106f1 100644
--- a/lib/manager/npm/post-update/index.ts
+++ b/lib/manager/npm/post-update/index.ts
@@ -8,7 +8,7 @@ import { logger } from '../../../logger';
 import { platform } from '../../../platform';
 import { ExternalHostError } from '../../../types/errors/external-host-error';
 import { getChildProcessEnv } from '../../../util/exec/env';
-import { deleteLocalFile } from '../../../util/fs';
+import { deleteLocalFile } from '../../../util/gitfs';
 import * as hostRules from '../../../util/host-rules';
 import { PackageFile, PostUpdateConfig, Upgrade } from '../../common';
 import * as lerna from './lerna';
diff --git a/lib/manager/npm/post-update/node-version.spec.ts b/lib/manager/npm/post-update/node-version.spec.ts
index e529d1d3236f6923b7209d9cba3d26e4605614bb..fb3d4c9e14863292cd787099aad242f0fe5eb38f 100644
--- a/lib/manager/npm/post-update/node-version.spec.ts
+++ b/lib/manager/npm/post-update/node-version.spec.ts
@@ -1,8 +1,10 @@
 import { mocked } from '../../../../test/util';
-import * as fs_ from '../../../util/fs';
+import * as _gitfs from '../../../util/gitfs';
 import { getNodeConstraint } from './node-version';
 
-const fs = mocked(fs_);
+jest.mock('../../../util/gitfs');
+
+const gitfs = mocked(_gitfs);
 
 describe('getNodeConstraint', () => {
   const config = {
@@ -10,36 +12,36 @@ describe('getNodeConstraint', () => {
     compatibility: { node: '^12.16.0' },
   };
   it('returns package.json range', async () => {
-    fs.readLocalFile = jest.fn();
-    fs.readLocalFile.mockResolvedValueOnce(null);
-    fs.readLocalFile.mockResolvedValueOnce(null);
+    gitfs.readLocalFile = jest.fn();
+    gitfs.readLocalFile.mockResolvedValueOnce(null);
+    gitfs.readLocalFile.mockResolvedValueOnce(null);
     const res = await getNodeConstraint(config);
     expect(res).toEqual('^12.16.0');
   });
   it('returns .node-version value', async () => {
-    fs.readLocalFile = jest.fn();
-    fs.readLocalFile.mockResolvedValueOnce(null);
-    fs.readLocalFile.mockResolvedValueOnce('12.16.1\n');
+    gitfs.readLocalFile = jest.fn();
+    gitfs.readLocalFile.mockResolvedValueOnce(null);
+    gitfs.readLocalFile.mockResolvedValueOnce('12.16.1\n');
     const res = await getNodeConstraint(config);
     expect(res).toEqual('12.16.1');
   });
   it('returns .nvmrc value', async () => {
-    fs.readLocalFile = jest.fn();
-    fs.readLocalFile.mockResolvedValueOnce('12.16.2\n');
+    gitfs.readLocalFile = jest.fn();
+    gitfs.readLocalFile.mockResolvedValueOnce('12.16.2\n');
     const res = await getNodeConstraint(config);
     expect(res).toEqual('12.16.2');
   });
   it('ignores unusable ranges in dotfiles', async () => {
-    fs.readLocalFile = jest.fn();
-    fs.readLocalFile.mockResolvedValueOnce('latest');
-    fs.readLocalFile.mockResolvedValueOnce('lts');
+    gitfs.readLocalFile = jest.fn();
+    gitfs.readLocalFile.mockResolvedValueOnce('latest');
+    gitfs.readLocalFile.mockResolvedValueOnce('lts');
     const res = await getNodeConstraint(config);
     expect(res).toEqual('^12.16.0');
   });
   it('returns no constraint', async () => {
-    fs.readLocalFile = jest.fn();
-    fs.readLocalFile.mockResolvedValueOnce(null);
-    fs.readLocalFile.mockResolvedValueOnce(null);
+    gitfs.readLocalFile = jest.fn();
+    gitfs.readLocalFile.mockResolvedValueOnce(null);
+    gitfs.readLocalFile.mockResolvedValueOnce(null);
     const res = await getNodeConstraint({ ...config, compatibility: null });
     expect(res).toBeNull();
   });
diff --git a/lib/manager/npm/post-update/node-version.ts b/lib/manager/npm/post-update/node-version.ts
index b929499b63137e88f8dc17426cdbfcab2bdb9106..aa0be56fbf3759799d076d5580fc7a6c9059b900 100644
--- a/lib/manager/npm/post-update/node-version.ts
+++ b/lib/manager/npm/post-update/node-version.ts
@@ -1,6 +1,6 @@
 import { validRange } from 'semver';
 import { logger } from '../../../logger';
-import { getSiblingFileName, readLocalFile } from '../../../util/fs';
+import { getSiblingFileName, readLocalFile } from '../../../util/gitfs';
 import { PostUpdateConfig } from '../../common';
 
 async function getNodeFile(filename: string): Promise<string> | null {
diff --git a/lib/manager/pip_requirements/artifacts.ts b/lib/manager/pip_requirements/artifacts.ts
index 98a3bfeb82bce808e192cb3c2cc39f22416e2c2a..f0f175a622237850f5c3cb4525bfb4dba0f2f962 100644
--- a/lib/manager/pip_requirements/artifacts.ts
+++ b/lib/manager/pip_requirements/artifacts.ts
@@ -1,7 +1,7 @@
 import is from '@sindresorhus/is';
 import { logger } from '../../logger';
 import { ExecOptions, exec } from '../../util/exec';
-import { readLocalFile } from '../../util/fs';
+import { readLocalFile } from '../../util/gitfs';
 import { UpdateArtifact, UpdateArtifactsResult } from '../common';
 
 export async function updateArtifacts({
diff --git a/lib/manager/pipenv/artifacts.ts b/lib/manager/pipenv/artifacts.ts
index 9e33a4dd91b4d709a390cc3c826361ffd7dfe271..a82a43471132f20ae6de4de9e9ca45d306e3c8f8 100644
--- a/lib/manager/pipenv/artifacts.ts
+++ b/lib/manager/pipenv/artifacts.ts
@@ -3,7 +3,7 @@ import { join } from 'upath';
 import { logger } from '../../logger';
 import { platform } from '../../platform';
 import { ExecOptions, exec } from '../../util/exec';
-import { readLocalFile } from '../../util/fs';
+import { readLocalFile } from '../../util/gitfs';
 import {
   UpdateArtifact,
   UpdateArtifactsConfig,
diff --git a/lib/manager/poetry/artifacts.ts b/lib/manager/poetry/artifacts.ts
index 9c6c87c508a9e0cce7290e1b5dab3dfc4eaaabc2..0da8632431b770f61a5dd679d2cebc6b18b69284 100644
--- a/lib/manager/poetry/artifacts.ts
+++ b/lib/manager/poetry/artifacts.ts
@@ -8,7 +8,7 @@ import {
   getSiblingFileName,
   readLocalFile,
   writeLocalFile,
-} from '../../util/fs';
+} from '../../util/gitfs';
 import {
   UpdateArtifact,
   UpdateArtifactsConfig,
diff --git a/lib/util/fs.spec.ts b/lib/util/gitfs/fs.spec.ts
similarity index 92%
rename from lib/util/fs.spec.ts
rename to lib/util/gitfs/fs.spec.ts
index 10199a460d821cdbf4e222260322576eef6d60b4..bcbf606cf5f9be3abdaf2d9ea023c2642ec419d0 100644
--- a/lib/util/fs.spec.ts
+++ b/lib/util/gitfs/fs.spec.ts
@@ -1,4 +1,4 @@
-import { getName } from '../../test/util';
+import { getName } from '../../../test/util';
 import { readLocalFile } from './fs';
 
 describe(getName(__filename), () => {
diff --git a/lib/util/fs.ts b/lib/util/gitfs/fs.ts
similarity index 94%
rename from lib/util/fs.ts
rename to lib/util/gitfs/fs.ts
index d94bb19c37386a77fcb601a837ed7c60d28f19a2..b94d2c2364106a3b6d92c5e7abe5f7f1319ab8be 100644
--- a/lib/util/fs.ts
+++ b/lib/util/gitfs/fs.ts
@@ -1,7 +1,7 @@
 import * as fs from 'fs-extra';
 import { join, parse } from 'upath';
-import { RenovateConfig } from '../config/common';
-import { logger } from '../logger';
+import { RenovateConfig } from '../../config/common';
+import { logger } from '../../logger';
 
 let localDir = '';
 
diff --git a/lib/util/gitfs/index.ts b/lib/util/gitfs/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c6a897d250b7ed79c99df80349bbb11895d9a00b
--- /dev/null
+++ b/lib/util/gitfs/index.ts
@@ -0,0 +1 @@
+export * from './fs';
diff --git a/lib/util/index.ts b/lib/util/index.ts
index 58b1c8631c67884d7eb1e5669c3f3f613b7453bc..c72f151a0a852ba70aad528f23f5dd1194dbd1af 100644
--- a/lib/util/index.ts
+++ b/lib/util/index.ts
@@ -2,7 +2,7 @@ import findUp from 'find-up';
 import { join } from 'upath';
 import { RenovateConfig } from '../config/common';
 import { setExecConfig } from './exec';
-import { setFsConfig } from './fs';
+import { setFsConfig } from './gitfs';
 
 export async function setUtilConfig(
   config: Partial<RenovateConfig>
diff --git a/lib/workers/branch/auto-replace.spec.ts b/lib/workers/branch/auto-replace.spec.ts
index 3ab53b7745e040313c803f8116c7d090701badc2..f0a297b0242eca40022fd89463d65fd12c819bf2 100644
--- a/lib/workers/branch/auto-replace.spec.ts
+++ b/lib/workers/branch/auto-replace.spec.ts
@@ -10,7 +10,7 @@ const sampleHtml = readFileSync(
   'utf8'
 );
 
-jest.mock('../../util/fs');
+jest.mock('../../util/gitfs');
 
 describe('workers/branch/auto-replace', () => {
   describe('doAutoReplace', () => {
diff --git a/lib/workers/branch/auto-replace.ts b/lib/workers/branch/auto-replace.ts
index 0cd88d02e3912b626dc1e9cea8c850c83f79af5a..6d17fa28e45e77492a5f07d49bbcf84863bea67c 100644
--- a/lib/workers/branch/auto-replace.ts
+++ b/lib/workers/branch/auto-replace.ts
@@ -2,7 +2,7 @@ import { WORKER_FILE_UPDATE_FAILED } from '../../constants/error-messages';
 import { logger } from '../../logger';
 import { get } from '../../manager';
 import { PackageDependency } from '../../manager/common';
-import { writeLocalFile } from '../../util/fs';
+import { writeLocalFile } from '../../util/gitfs';
 import { escapeRegExp, regEx } from '../../util/regex';
 import { matchAt, replaceAt } from '../../util/string';
 import { compile } from '../../util/template';
diff --git a/lib/workers/branch/index.ts b/lib/workers/branch/index.ts
index ce865f3cc70c466de415cda7821987f16ab6d386..f5f4521e180abc282c8be37963d32fcb4d8db76f 100644
--- a/lib/workers/branch/index.ts
+++ b/lib/workers/branch/index.ts
@@ -24,7 +24,7 @@ import { BranchStatus } from '../../types';
 import { ExternalHostError } from '../../types/errors/external-host-error';
 import { emojify } from '../../util/emoji';
 import { exec } from '../../util/exec';
-import { readLocalFile, writeLocalFile } from '../../util/fs';
+import { readLocalFile, writeLocalFile } from '../../util/gitfs';
 import { regEx } from '../../util/regex';
 import { BranchConfig, PrResult, ProcessBranchResult } from '../common';
 import { checkAutoMerge, ensurePr } from '../pr';
diff --git a/lib/workers/repository/extract/manager-files.spec.ts b/lib/workers/repository/extract/manager-files.spec.ts
index 482547ae7f6d172afcddfe5c0709f0696d12a8ef..f68fddc3e591ecd31b8ee03f3587356092cdfce3 100644
--- a/lib/workers/repository/extract/manager-files.spec.ts
+++ b/lib/workers/repository/extract/manager-files.spec.ts
@@ -1,15 +1,15 @@
 import { getConfig, mocked } from '../../../../test/util';
 import { RenovateConfig } from '../../../config';
 import * as _html from '../../../manager/html';
-import * as _fs from '../../../util/fs';
+import * as _gitfs from '../../../util/gitfs';
 import * as _fileMatch from './file-match';
 import { getManagerPackageFiles } from './manager-files';
 
 jest.mock('./file-match');
 jest.mock('../../../manager/html');
-jest.mock('../../../util/fs');
+jest.mock('../../../util/gitfs');
 
-const fs: any = _fs;
+const gitfs: any = _gitfs;
 const fileMatch = mocked(_fileMatch);
 const html = mocked(_html);
 
@@ -44,7 +44,7 @@ describe('workers/repository/extract/manager-files', () => {
         fileList: ['Dockerfile'],
       };
       fileMatch.getMatchingFiles.mockResolvedValue(['Dockerfile']);
-      fs.readLocalFile.mockResolvedValueOnce('some content');
+      gitfs.readLocalFile.mockResolvedValueOnce('some content');
       html.extractPackageFile = jest.fn(() => ({
         deps: [{}, { replaceString: 'abc' }],
       })) as never;
@@ -58,7 +58,7 @@ describe('workers/repository/extract/manager-files', () => {
         fileList: ['package.json'],
       };
       fileMatch.getMatchingFiles.mockResolvedValue(['package.json']);
-      fs.readLocalFile.mockResolvedValueOnce(
+      gitfs.readLocalFile.mockResolvedValueOnce(
         '{"dependencies":{"chalk":"2.0.0"}}'
       );
       const res = await getManagerPackageFiles(managerConfig);
diff --git a/lib/workers/repository/extract/manager-files.ts b/lib/workers/repository/extract/manager-files.ts
index c3e8880ffccc0c8ca74f20bdb13482d5493d8b53..374b7974f3285574e5e2a5a1c4edcfb7010fd6c6 100644
--- a/lib/workers/repository/extract/manager-files.ts
+++ b/lib/workers/repository/extract/manager-files.ts
@@ -7,7 +7,7 @@ import {
   get,
 } from '../../../manager';
 import { PackageFile } from '../../../manager/common';
-import { readLocalFile } from '../../../util/fs';
+import { readLocalFile } from '../../../util/gitfs';
 
 export async function getManagerPackageFiles(
   config: RenovateConfig
diff --git a/lib/workers/repository/init/config.spec.ts b/lib/workers/repository/init/config.spec.ts
index 38a3c5e8809cb0240704e383c0861e2ef5a7b4ab..ae19098d5275274fbdac5845421722fe6374c6a4 100644
--- a/lib/workers/repository/init/config.spec.ts
+++ b/lib/workers/repository/init/config.spec.ts
@@ -1,14 +1,14 @@
 import {
   RenovateConfig,
-  fs,
   getConfig,
+  gitfs,
   mocked,
   platform,
 } from '../../../../test/util';
 import * as _migrateAndValidate from '../../../config/migrate-validate';
 import { mergeRenovateConfig } from './config';
 
-jest.mock('../../../util/fs');
+jest.mock('../../../util/gitfs');
 
 const migrateAndValidate = mocked(_migrateAndValidate);
 
@@ -32,7 +32,7 @@ describe('workers/repository/init/config', () => {
     });
     it('returns config if not found', async () => {
       platform.getFileList.mockResolvedValue(['package.json']);
-      fs.readLocalFile.mockResolvedValue('{}');
+      gitfs.readLocalFile.mockResolvedValue('{}');
       const res = await mergeRenovateConfig(config);
       expect(res).toMatchObject(config);
     });
@@ -44,13 +44,13 @@ describe('workers/repository/init/config', () => {
           prHourlyLimit: 10,
         },
       });
-      fs.readLocalFile.mockResolvedValue(pJson);
+      gitfs.readLocalFile.mockResolvedValue(pJson);
       const renovateConfig = await mergeRenovateConfig(config);
       expect(renovateConfig).toBeTruthy();
     });
     it('returns error if cannot parse', async () => {
       platform.getFileList.mockResolvedValue(['package.json', 'renovate.json']);
-      fs.readLocalFile.mockResolvedValue('cannot parse');
+      gitfs.readLocalFile.mockResolvedValue('cannot parse');
       let e;
       try {
         await mergeRenovateConfig(config);
@@ -64,7 +64,7 @@ describe('workers/repository/init/config', () => {
     });
     it('throws error if duplicate keys', async () => {
       platform.getFileList.mockResolvedValue(['package.json', '.renovaterc']);
-      fs.readLocalFile.mockResolvedValue(
+      gitfs.readLocalFile.mockResolvedValue(
         '{ "enabled": true, "enabled": false }'
       );
       let e;
@@ -83,7 +83,7 @@ describe('workers/repository/init/config', () => {
         'package.json',
         'renovate.json5',
       ]);
-      fs.readLocalFile.mockResolvedValue(`{
+      gitfs.readLocalFile.mockResolvedValue(`{
         // this is json5 format
       }`);
       const renovateConfig = await mergeRenovateConfig(config);
@@ -94,7 +94,7 @@ describe('workers/repository/init/config', () => {
         'package.json',
         '.github/renovate.json',
       ]);
-      fs.readLocalFile.mockResolvedValue('{}');
+      gitfs.readLocalFile.mockResolvedValue('{}');
       const renovateConfig = await mergeRenovateConfig(config);
       expect(renovateConfig).toBeTruthy();
     });
@@ -103,7 +103,7 @@ describe('workers/repository/init/config', () => {
         'package.json',
         '.gitlab/renovate.json',
       ]);
-      fs.readLocalFile.mockResolvedValue('{}');
+      gitfs.readLocalFile.mockResolvedValue('{}');
       const renovateConfig = await mergeRenovateConfig(config);
       expect(renovateConfig).toBeTruthy();
     });
@@ -112,7 +112,7 @@ describe('workers/repository/init/config', () => {
         'package.json',
         '.renovaterc.json',
       ]);
-      fs.readLocalFile.mockResolvedValue('{}');
+      gitfs.readLocalFile.mockResolvedValue('{}');
       const renovateConfig = await mergeRenovateConfig(config);
       expect(renovateConfig).toBeTruthy();
     });
@@ -121,7 +121,7 @@ describe('workers/repository/init/config', () => {
         'package.json',
         '.renovaterc.json',
       ]);
-      fs.readLocalFile.mockResolvedValue('{}');
+      gitfs.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 2eeb01658605d054bcd450df4e8f8b85277d56ea..cdc7d8fa1fc14955420cb561a5fa6517918d11cd 100644
--- a/lib/workers/repository/init/config.ts
+++ b/lib/workers/repository/init/config.ts
@@ -12,7 +12,7 @@ import * as npmApi from '../../../datasource/npm';
 import { logger } from '../../../logger';
 import { platform } from '../../../platform';
 import { ExternalHostError } from '../../../types/errors/external-host-error';
-import { readLocalFile } from '../../../util/fs';
+import { readLocalFile } from '../../../util/gitfs';
 import * as hostRules from '../../../util/host-rules';
 import { flattenPackageRules } from './flatten';
 
diff --git a/lib/workers/repository/onboarding/branch/check.ts b/lib/workers/repository/onboarding/branch/check.ts
index 363c697cec7548f3c84a65069b5f67342b5d95ca..bf6baab0aedd0a490657582c78b0b169b923bc72 100644
--- a/lib/workers/repository/onboarding/branch/check.ts
+++ b/lib/workers/repository/onboarding/branch/check.ts
@@ -4,7 +4,7 @@ import { REPOSITORY_DISABLED } from '../../../../constants/error-messages';
 import { PR_STATE_NOT_OPEN } from '../../../../constants/pull-requests';
 import { logger } from '../../../../logger';
 import { platform } from '../../../../platform';
-import { readLocalFile } from '../../../../util/fs';
+import { readLocalFile } from '../../../../util/gitfs';
 
 const findFile = async (fileName: string): Promise<boolean> => {
   logger.debug(`findFile(${fileName})`);
diff --git a/lib/workers/repository/onboarding/branch/config.ts b/lib/workers/repository/onboarding/branch/config.ts
index 45cee4492b8ebde0151fa621dfbda41b2e6b99c8..5ebfb796df02d302d6d0299a65fa8771091ed65b 100644
--- a/lib/workers/repository/onboarding/branch/config.ts
+++ b/lib/workers/repository/onboarding/branch/config.ts
@@ -2,7 +2,7 @@ import is from '@sindresorhus/is';
 import { RenovateConfig } from '../../../../config';
 import { logger } from '../../../../logger';
 import { clone } from '../../../../util/clone';
-import { readLocalFile } from '../../../../util/fs';
+import { readLocalFile } from '../../../../util/gitfs';
 
 export async function getOnboardingConfig(
   config: RenovateConfig
diff --git a/lib/workers/repository/onboarding/branch/index.spec.ts b/lib/workers/repository/onboarding/branch/index.spec.ts
index a9d53d2703ac9eb08b4e4f39a05b77973fef14eb..7df826de279d6ef8b384a762e6ecd897f77fd9ec 100644
--- a/lib/workers/repository/onboarding/branch/index.spec.ts
+++ b/lib/workers/repository/onboarding/branch/index.spec.ts
@@ -1,8 +1,8 @@
 import { mock } from 'jest-mock-extended';
 import {
   RenovateConfig,
-  fs,
   getConfig,
+  gitfs,
   platform,
 } from '../../../../../test/util';
 import { PR_STATE_OPEN } from '../../../../constants/pull-requests';
@@ -13,7 +13,7 @@ import { checkOnboardingBranch } from '.';
 const rebase: any = _rebase;
 
 jest.mock('../../../../workers/repository/onboarding/branch/rebase');
-jest.mock('../../../../util/fs');
+jest.mock('../../../../util/gitfs');
 
 describe('workers/repository/onboarding/branch', () => {
   describe('checkOnboardingBranch', () => {
@@ -32,7 +32,7 @@ describe('workers/repository/onboarding/branch', () => {
     });
     it('has default onboarding config', async () => {
       platform.getFileList.mockResolvedValue(['package.json']);
-      fs.readLocalFile.mockResolvedValue('{}');
+      gitfs.readLocalFile.mockResolvedValue('{}');
       await checkOnboardingBranch(config);
       expect(
         platform.commitFiles.mock.calls[0][0].files[0].contents
@@ -55,7 +55,7 @@ describe('workers/repository/onboarding/branch', () => {
       config.requireConfig = true;
       config.onboarding = false;
       platform.getFileList.mockResolvedValueOnce(['package.json']);
-      fs.readLocalFile.mockResolvedValueOnce('{}');
+      gitfs.readLocalFile.mockResolvedValueOnce('{}');
       const onboardingResult = checkOnboardingBranch(config);
       await expect(onboardingResult).rejects.toThrow('disabled');
     });
@@ -66,7 +66,7 @@ describe('workers/repository/onboarding/branch', () => {
     });
     it('detects repo is onboarded via package.json config', async () => {
       platform.getFileList.mockResolvedValueOnce(['package.json']);
-      fs.readLocalFile.mockResolvedValueOnce('{"renovate":{}}');
+      gitfs.readLocalFile.mockResolvedValueOnce('{"renovate":{}}');
       const res = await checkOnboardingBranch(config);
       expect(res.repoIsOnboarded).toBe(true);
     });
@@ -99,7 +99,7 @@ describe('workers/repository/onboarding/branch', () => {
           ignore: ['foo', 'bar'],
         },
       });
-      fs.readLocalFile.mockResolvedValue(pJsonContent);
+      gitfs.readLocalFile.mockResolvedValue(pJsonContent);
       platform.commitFiles.mockResolvedValueOnce('abc123');
       await checkOnboardingBranch(config);
       expect(
diff --git a/test/util.ts b/test/util.ts
index b00cef32eb936b495bff85ba1673f1841940f23b..90f324bd058442e9935d7fb52d9ef131a1f0bd8a 100644
--- a/test/util.ts
+++ b/test/util.ts
@@ -4,7 +4,7 @@ import { RenovateConfig as _RenovateConfig } from '../lib/config';
 import { getConfig } from '../lib/config/defaults';
 import { platform as _platform } from '../lib/platform';
 import * as _env from '../lib/util/exec/env';
-import * as _fs from '../lib/util/fs';
+import * as _gitfs from '../lib/util/gitfs';
 import * as _hostRules from '../lib/util/host-rules';
 
 /**
@@ -23,7 +23,7 @@ export function partial<T>(obj: Partial<T>): T {
   return obj as T;
 }
 
-export const fs = mocked(_fs);
+export const gitfs = mocked(_gitfs);
 export const platform = mocked(_platform);
 export const env = mocked(_env);
 export const hostRules = mocked(_hostRules);