diff --git a/.eslintrc.js b/.eslintrc.js
index 95517d09e2761751cd9af03e294969ca73262623..259a035c36bb55f6e2065d55cd141826cafd960a 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -41,6 +41,8 @@ module.exports = {
     ],
     'import/prefer-default-export': 0, // no benefit
 
+    'import/no-cycle': 2, // cycles don't work when moving to esm
+
     /*
      * This rule is not needed since the project uses typescript and the rule
      * `@typescript-eslint/explicit-function-return-type`.
diff --git a/lib/modules/manager/bazel/parser.spec.ts b/lib/modules/manager/bazel/parser.spec.ts
index d99cef0b22688b5da04d95d8e9a37e0a57394940..42dc65c863430ccd7f54053772fd18cd3a00fe51 100644
--- a/lib/modules/manager/bazel/parser.spec.ts
+++ b/lib/modules/manager/bazel/parser.spec.ts
@@ -1,4 +1,5 @@
-import { extract, parse } from './parser';
+import { parse } from './parser';
+import { extract } from './rules';
 
 describe('modules/manager/bazel/parser', () => {
   it('parses rules input', () => {
diff --git a/lib/modules/manager/bazel/parser.ts b/lib/modules/manager/bazel/parser.ts
index 9b2a18d87b5fe877f2e1b3e4dfa43ab54ec7f27a..776f38673d3c0e599a7e23654732f1737196fd20 100644
--- a/lib/modules/manager/bazel/parser.ts
+++ b/lib/modules/manager/bazel/parser.ts
@@ -2,13 +2,8 @@ import { lang, lexer, parser, query as q } from 'good-enough-parser';
 import hasha from 'hasha';
 import { logger } from '../../../logger';
 import * as memCache from '../../../util/cache/memory';
-import { supportedRulesRegex } from './rules/index';
-import type {
-  Fragment,
-  FragmentData,
-  NestedFragment,
-  RecordFragment,
-} from './types';
+import { supportedRulesRegex } from './rules';
+import type { NestedFragment, RecordFragment } from './types';
 
 interface Ctx {
   readonly source: string;
@@ -231,20 +226,3 @@ export function parse(
   memCache.set(cacheKey, result);
   return result;
 }
-
-export function extract(fragment: Fragment): FragmentData {
-  if (fragment.type === 'string') {
-    return fragment.value;
-  }
-
-  if (fragment.type === 'record') {
-    const { children } = fragment;
-    const result: Record<string, FragmentData> = {};
-    for (const [key, value] of Object.entries(children)) {
-      result[key] = extract(value);
-    }
-    return result;
-  }
-
-  return fragment.children.map(extract);
-}
diff --git a/lib/modules/manager/bazel/rules/index.ts b/lib/modules/manager/bazel/rules/index.ts
index 8296c4514d2fa673d22762ebe873b165ed2220e9..deafa4d077048c8fe308324aa4d97cd7a7074f97 100644
--- a/lib/modules/manager/bazel/rules/index.ts
+++ b/lib/modules/manager/bazel/rules/index.ts
@@ -1,7 +1,6 @@
 import { z } from 'zod';
 import { regEx } from '../../../../util/regex';
 import type { PackageDependency } from '../../types';
-import { extract } from '../parser';
 import type { Fragment, FragmentData, Target } from '../types';
 import { DockerTarget, dockerRules } from './docker';
 import { GitTarget, gitRules } from './git';
@@ -33,3 +32,20 @@ export function extractDepFromFragment(
   const fragmentData = extract(fragment);
   return extractDepFromFragmentData(fragmentData);
 }
+
+export function extract(fragment: Fragment): FragmentData {
+  if (fragment.type === 'string') {
+    return fragment.value;
+  }
+
+  if (fragment.type === 'record') {
+    const { children } = fragment;
+    const result: Record<string, FragmentData> = {};
+    for (const [key, value] of Object.entries(children)) {
+      result[key] = extract(value);
+    }
+    return result;
+  }
+
+  return fragment.children.map(extract);
+}
diff --git a/lib/modules/manager/gradle/artifacts.spec.ts b/lib/modules/manager/gradle/artifacts.spec.ts
index f2856dc899b50aedc2bca56556bb4074e7278fd7..fffb4314e4c67401ba554c15e8dcea2bf0ae0486 100644
--- a/lib/modules/manager/gradle/artifacts.spec.ts
+++ b/lib/modules/manager/gradle/artifacts.spec.ts
@@ -68,7 +68,7 @@ describe('modules/manager/gradle/artifacts', () => {
       'gradle.lockfile',
       'gradle/wrapper/gradle-wrapper.properties',
     ]);
-    fs.getFileContentMap.mockResolvedValue({
+    git.getFiles.mockResolvedValue({
       'gradle.lockfile': 'Current gradle.lockfile',
     });
     git.getRepoStatus.mockResolvedValue(
diff --git a/lib/modules/manager/gradle/artifacts.ts b/lib/modules/manager/gradle/artifacts.ts
index 8f7a384b7be49eadd304629aeccdb9e2f80f357f..3247d4230d5ce85103172642ef100b1220d22803 100644
--- a/lib/modules/manager/gradle/artifacts.ts
+++ b/lib/modules/manager/gradle/artifacts.ts
@@ -5,13 +5,8 @@ import { TEMPORARY_ERROR } from '../../../constants/error-messages';
 import { logger } from '../../../logger';
 import { exec } from '../../../util/exec';
 import type { ExecOptions } from '../../../util/exec/types';
-import {
-  findUpLocal,
-  getFileContentMap,
-  readLocalFile,
-  writeLocalFile,
-} from '../../../util/fs';
-import { getFileList, getRepoStatus } from '../../../util/git';
+import { findUpLocal, readLocalFile, writeLocalFile } from '../../../util/fs';
+import { getFileList, getFiles, getRepoStatus } from '../../../util/git';
 import { regEx } from '../../../util/regex';
 import {
   extraEnv,
@@ -128,7 +123,7 @@ export async function updateArtifacts({
   logger.debug('Updating found Gradle dependency lockfiles');
 
   try {
-    const oldLockFileContentMap = await getFileContentMap(lockFiles);
+    const oldLockFileContentMap = await getFiles(lockFiles);
 
     await writeLocalFile(packageFileName, newPackageFileContent);
     await prepareGradleCommand(gradlewFile);
diff --git a/lib/modules/manager/gradle/extract.spec.ts b/lib/modules/manager/gradle/extract.spec.ts
index c63b0e3a6634eb10ad7dc596bdea314cdeac75b7..2e8450d65d4d9f4c6ab05f86468b4c5c15d9efb7 100644
--- a/lib/modules/manager/gradle/extract.spec.ts
+++ b/lib/modules/manager/gradle/extract.spec.ts
@@ -9,16 +9,14 @@ jest.mock('../../../util/fs');
 
 function mockFs(files: Record<string, string>): void {
   // TODO: fix types, jest is using wrong overload (#7154)
-  fs.getFileContentMap.mockImplementation(
-    (fileNames: string[]): Promise<any> => {
-      const fileContentMap: Record<string, string | null> = {};
-      for (const fileName of fileNames) {
-        fileContentMap[fileName] = files?.[fileName];
-      }
-
-      return Promise.resolve(fileContentMap);
+  fs.getLocalFiles.mockImplementation((fileNames: string[]): Promise<any> => {
+    const fileContentMap: Record<string, string | null> = {};
+    for (const fileName of fileNames) {
+      fileContentMap[fileName] = files?.[fileName];
     }
-  );
+
+    return Promise.resolve(fileContentMap);
+  });
 
   fs.getSiblingFileName.mockImplementation(
     (existingFileNameWithPath: string, otherFileName: string) => {
diff --git a/lib/modules/manager/gradle/extract.ts b/lib/modules/manager/gradle/extract.ts
index 7053716f06ed30af009a00442c8ea73f51fd3d23..8d2f78ff140fb83d8eed9739ed6d3e849e71d3f2 100644
--- a/lib/modules/manager/gradle/extract.ts
+++ b/lib/modules/manager/gradle/extract.ts
@@ -1,6 +1,6 @@
 import upath from 'upath';
 import { logger } from '../../../logger';
-import { getFileContentMap } from '../../../util/fs';
+import { getLocalFiles } from '../../../util/fs';
 import { MavenDatasource } from '../../datasource/maven';
 import type { ExtractConfig, PackageDependency, PackageFile } from '../types';
 import { parseCatalog } from './extract/catalog';
@@ -54,7 +54,7 @@ export async function extractAllPackageFiles(
   const packageFilesByName: Record<string, PackageFile> = {};
   const packageRegistries: PackageRegistry[] = [];
   const reorderedFiles = reorderFiles(packageFiles);
-  const fileContents = await getFileContentMap(packageFiles, true);
+  const fileContents = await getLocalFiles(packageFiles);
 
   for (const packageFile of reorderedFiles) {
     packageFilesByName[packageFile] = {
diff --git a/lib/modules/manager/gradle/parser.ts b/lib/modules/manager/gradle/parser.ts
index 44fd6066b4f2c831ebbf878e3b371d0219eb88f7..02a788145d25c7bbcd507b942687a46dcee0bd13 100644
--- a/lib/modules/manager/gradle/parser.ts
+++ b/lib/modules/manager/gradle/parser.ts
@@ -4,6 +4,7 @@ import type { PackageDependency } from '../types';
 import { qApplyFrom } from './parser/apply-from';
 import { qAssignments } from './parser/assignments';
 import { qDependencies, qLongFormDep } from './parser/dependencies';
+import { setParseGradleFunc } from './parser/handlers';
 import { qPlugins } from './parser/plugins';
 import { qRegistryUrls } from './parser/registry-urls';
 import { qVersionCatalogs } from './parser/version-catalogs';
@@ -18,6 +19,8 @@ import { isDependencyString, parseDependencyString } from './utils';
 
 const groovy = lang.createLang('groovy');
 
+setParseGradleFunc(parseGradle);
+
 export function parseGradle(
   input: string,
   initVars: PackageVariables = {},
diff --git a/lib/modules/manager/gradle/parser/handlers.ts b/lib/modules/manager/gradle/parser/handlers.ts
index 8e2044bb4a483bbc4784f243e35badc1229a2d64..9ab3f4dd9a414bc70ee579f6eeffc9b5a170bd41 100644
--- a/lib/modules/manager/gradle/parser/handlers.ts
+++ b/lib/modules/manager/gradle/parser/handlers.ts
@@ -4,7 +4,7 @@ import { logger } from '../../../../logger';
 import { getSiblingFileName } from '../../../../util/fs';
 import { regEx } from '../../../../util/regex';
 import type { PackageDependency } from '../../types';
-import { parseGradle } from '../parser';
+import type { parseGradle as parseGradleCallback } from '../parser';
 import type { Ctx, GradleManagerData } from '../types';
 import { parseDependencyString } from '../utils';
 import {
@@ -15,6 +15,12 @@ import {
   loadFromTokenMap,
 } from './common';
 
+// needed to break circular dependency
+let parseGradle: typeof parseGradleCallback;
+export function setParseGradleFunc(func: typeof parseGradleCallback): void {
+  parseGradle = func;
+}
+
 export function handleAssignment(ctx: Ctx): Ctx {
   const key = loadFromTokenMap(ctx, 'keyToken')[0].value;
   const valTokens = loadFromTokenMap(ctx, 'valToken');
diff --git a/lib/modules/manager/nuget/artifacts.spec.ts b/lib/modules/manager/nuget/artifacts.spec.ts
index 7ed9178d22b1b6e8014edfde2023b20c922baad3..aa22079b096e2c8ee1e63d34eb40d9f8db5a2b94 100644
--- a/lib/modules/manager/nuget/artifacts.spec.ts
+++ b/lib/modules/manager/nuget/artifacts.spec.ts
@@ -51,7 +51,7 @@ describe('modules/manager/nuget/artifacts', () => {
   it('aborts if no lock file found', async () => {
     const execSnapshots = mockExecAll();
     fs.getSiblingFileName.mockReturnValueOnce('packages.lock.json');
-    fs.getFileContentMap.mockResolvedValueOnce({ 'packages.lock.json': null });
+    git.getFiles.mockResolvedValueOnce({ 'packages.lock.json': null });
     expect(
       await nuget.updateArtifacts({
         packageFileName: 'project.csproj',
@@ -68,13 +68,12 @@ describe('modules/manager/nuget/artifacts', () => {
     fs.getSiblingFileName.mockReturnValueOnce(
       'path/with space/packages.lock.json'
     );
-    fs.getFileContentMap
-      .mockResolvedValueOnce({
-        'path/with space/packages.lock.json': 'Current packages.lock.json',
-      })
-      .mockResolvedValueOnce({
-        'path/with space/packages.lock.json': 'Current packages.lock.json',
-      });
+    git.getFiles.mockResolvedValueOnce({
+      'path/with space/packages.lock.json': 'Current packages.lock.json',
+    });
+    fs.getLocalFiles.mockResolvedValueOnce({
+      'path/with space/packages.lock.json': 'Current packages.lock.json',
+    });
     expect(
       await nuget.updateArtifacts({
         packageFileName: 'path/with space/project.csproj',
@@ -101,13 +100,12 @@ describe('modules/manager/nuget/artifacts', () => {
   it('updates lock file', async () => {
     const execSnapshots = mockExecAll();
     fs.getSiblingFileName.mockReturnValueOnce('packages.lock.json');
-    fs.getFileContentMap
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'Current packages.lock.json',
-      })
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'New packages.lock.json',
-      });
+    git.getFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'Current packages.lock.json',
+    });
+    fs.getLocalFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'New packages.lock.json',
+    });
     expect(
       await nuget.updateArtifacts({
         packageFileName: 'project.csproj',
@@ -142,13 +140,12 @@ describe('modules/manager/nuget/artifacts', () => {
   it('does not update lock file when non-proj file is changed', async () => {
     const execSnapshots = mockExecAll();
     fs.getSiblingFileName.mockReturnValueOnce('packages.lock.json');
-    fs.getFileContentMap
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'Current packages.lock.json',
-      })
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'New packages.lock.json',
-      });
+    git.getFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'Current packages.lock.json',
+    });
+    fs.getLocalFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'New packages.lock.json',
+    });
     expect(
       await nuget.updateArtifacts({
         packageFileName: 'otherfile.props',
@@ -163,13 +160,12 @@ describe('modules/manager/nuget/artifacts', () => {
   it('does not update lock file when no deps changed', async () => {
     const execSnapshots = mockExecAll();
     fs.getSiblingFileName.mockReturnValueOnce('packages.lock.json');
-    fs.getFileContentMap
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'Current packages.lock.json',
-      })
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'New packages.lock.json',
-      });
+    git.getFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'Current packages.lock.json',
+    });
+    fs.getLocalFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'New packages.lock.json',
+    });
     expect(
       await nuget.updateArtifacts({
         packageFileName: 'project.csproj',
@@ -184,13 +180,12 @@ describe('modules/manager/nuget/artifacts', () => {
   it('performs lock file maintenance', async () => {
     const execSnapshots = mockExecAll();
     fs.getSiblingFileName.mockReturnValueOnce('packages.lock.json');
-    fs.getFileContentMap
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'Current packages.lock.json',
-      })
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'New packages.lock.json',
-      });
+    git.getFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'Current packages.lock.json',
+    });
+    fs.getLocalFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'New packages.lock.json',
+    });
     expect(
       await nuget.updateArtifacts({
         packageFileName: 'project.csproj',
@@ -229,13 +224,12 @@ describe('modules/manager/nuget/artifacts', () => {
     GlobalConfig.set({ ...adminConfig, binarySource: 'docker' });
     const execSnapshots = mockExecAll();
     fs.getSiblingFileName.mockReturnValueOnce('packages.lock.json');
-    fs.getFileContentMap
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'Current packages.lock.json',
-      })
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'New packages.lock.json',
-      });
+    git.getFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'Current packages.lock.json',
+    });
+    fs.getLocalFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'New packages.lock.json',
+    });
     expect(
       await nuget.updateArtifacts({
         packageFileName: 'project.csproj',
@@ -292,13 +286,12 @@ describe('modules/manager/nuget/artifacts', () => {
     GlobalConfig.set({ ...adminConfig, binarySource: 'install' });
     const execSnapshots = mockExecAll();
     fs.getSiblingFileName.mockReturnValueOnce('packages.lock.json');
-    fs.getFileContentMap
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'Current packages.lock.json',
-      })
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'New packages.lock.json',
-      });
+    git.getFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'Current packages.lock.json',
+    });
+    fs.getLocalFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'New packages.lock.json',
+    });
     expect(
       await nuget.updateArtifacts({
         packageFileName: 'project.csproj',
@@ -349,13 +342,12 @@ describe('modules/manager/nuget/artifacts', () => {
     GlobalConfig.set({ ...adminConfig, binarySource: 'global' });
     const execSnapshots = mockExecAll();
     fs.getSiblingFileName.mockReturnValueOnce('packages.lock.json');
-    fs.getFileContentMap
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'Current packages.lock.json',
-      })
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'New packages.lock.json',
-      });
+    git.getFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'Current packages.lock.json',
+    });
+    fs.getLocalFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'New packages.lock.json',
+    });
     expect(
       await nuget.updateArtifacts({
         packageFileName: 'project.csproj',
@@ -390,7 +382,7 @@ describe('modules/manager/nuget/artifacts', () => {
   it('catches errors', async () => {
     const execSnapshots = mockExecAll();
     fs.getSiblingFileName.mockReturnValueOnce('packages.lock.json');
-    fs.getFileContentMap.mockResolvedValueOnce({
+    git.getFiles.mockResolvedValueOnce({
       'packages.lock.json': 'Current packages.lock.json',
     });
     fs.writeLocalFile.mockImplementationOnce(() => {
@@ -417,13 +409,12 @@ describe('modules/manager/nuget/artifacts', () => {
   it('authenticates at registries', async () => {
     const execSnapshots = mockExecAll();
     fs.getSiblingFileName.mockReturnValueOnce('packages.lock.json');
-    fs.getFileContentMap
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'Current packages.lock.json',
-      })
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'New packages.lock.json',
-      });
+    git.getFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'Current packages.lock.json',
+    });
+    fs.getLocalFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'New packages.lock.json',
+    });
     getConfiguredRegistries.mockResolvedValueOnce([
       {
         name: 'myRegistry',
@@ -473,13 +464,12 @@ describe('modules/manager/nuget/artifacts', () => {
   it('strips protocol version from feed url', async () => {
     const execSnapshots = mockExecAll();
     fs.getSiblingFileName.mockReturnValueOnce('packages.lock.json');
-    fs.getFileContentMap
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'Current packages.lock.json',
-      })
-      .mockResolvedValueOnce({
-        'packages.lock.json': 'New packages.lock.json',
-      });
+    git.getFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'Current packages.lock.json',
+    });
+    fs.getLocalFiles.mockResolvedValueOnce({
+      'packages.lock.json': 'New packages.lock.json',
+    });
     getConfiguredRegistries.mockResolvedValueOnce([
       {
         name: 'myRegistry',
diff --git a/lib/modules/manager/nuget/artifacts.ts b/lib/modules/manager/nuget/artifacts.ts
index aec59e1d7beb26c8642467c32fc9f7cacadab6cf..2d2f4e1a6af3bf5cc6538be0ed29b8a8d124ae85 100644
--- a/lib/modules/manager/nuget/artifacts.ts
+++ b/lib/modules/manager/nuget/artifacts.ts
@@ -6,12 +6,13 @@ import { exec } from '../../../util/exec';
 import type { ExecOptions } from '../../../util/exec/types';
 import {
   ensureDir,
-  getFileContentMap,
+  getLocalFiles,
   getSiblingFileName,
   outputCacheFile,
   privateCacheDir,
   writeLocalFile,
 } from '../../../util/fs';
+import { getFiles } from '../../../util/git';
 import * as hostRules from '../../../util/host-rules';
 import { regEx } from '../../../util/regex';
 import { NugetDatasource } from '../../datasource/nuget';
@@ -145,7 +146,7 @@ export async function updateArtifacts({
     getSiblingFileName(f.name, 'packages.lock.json')
   );
 
-  const existingLockFileContentMap = await getFileContentMap(lockFileNames);
+  const existingLockFileContentMap = await getFiles(lockFileNames);
 
   const hasLockFileContent = Object.values(existingLockFileContentMap).some(
     (val) => !!val
@@ -170,7 +171,7 @@ export async function updateArtifacts({
 
     await runDotnetRestore(packageFileName, packageFiles, config);
 
-    const newLockFileContentMap = await getFileContentMap(lockFileNames, true);
+    const newLockFileContentMap = await getLocalFiles(lockFileNames);
 
     const retArray: UpdateArtifactsResult[] = [];
     for (const lockFileName of lockFileNames) {
diff --git a/lib/util/fs/index.spec.ts b/lib/util/fs/index.spec.ts
index 2594f7e0247a4c3bd17ef93cab29965a3573af16..2e0af88fe02919236fd0396c1abcb748261742ef 100644
--- a/lib/util/fs/index.spec.ts
+++ b/lib/util/fs/index.spec.ts
@@ -2,7 +2,7 @@ import _findUp from 'find-up';
 import fs from 'fs-extra';
 import tmp, { DirectoryResult } from 'tmp-promise';
 import { join, resolve } from 'upath';
-import { git, mockedFunction } from '../../../test/util';
+import { mockedFunction } from '../../../test/util';
 import { GlobalConfig } from '../../config/global';
 import {
   cachePathExists,
@@ -14,7 +14,7 @@ import {
   ensureLocalDir,
   findLocalSiblingOrParent,
   findUpLocal,
-  getFileContentMap,
+  getLocalFiles,
   getParentDir,
   getSiblingFileName,
   listCacheDir,
@@ -464,7 +464,7 @@ describe('util/fs/index', () => {
     });
   });
 
-  describe('getFileContentMap', () => {
+  describe('getLocalFiles', () => {
     it('reads list of files from local fs', async () => {
       const fileContentMap = {
         file1: 'foobar',
@@ -473,22 +473,12 @@ describe('util/fs/index', () => {
 
       await fs.outputFile(`${localDir}/file1`, fileContentMap.file1);
       await fs.outputFile(`${localDir}/file2`, fileContentMap.file2);
-      const res = await getFileContentMap(Object.keys(fileContentMap), true);
-      expect(res).toStrictEqual(fileContentMap);
-    });
-
-    it('reads list of files from git', async () => {
-      const fileContentMap = {
-        file1: 'foobar',
-      };
-
-      git.getFile.mockResolvedValueOnce('foobar');
-      const res = await getFileContentMap(Object.keys(fileContentMap));
+      const res = await getLocalFiles(Object.keys(fileContentMap));
       expect(res).toStrictEqual(fileContentMap);
     });
 
     it('returns null as content if file is not found', async () => {
-      const res = await getFileContentMap(['invalidfile'], true);
+      const res = await getLocalFiles(['invalidfile']);
       expect(res).toStrictEqual({
         invalidfile: null,
       });
diff --git a/lib/util/fs/index.ts b/lib/util/fs/index.ts
index ae659c83243857a24cc34b6cc3f828a40a548800..68c16d04e180a6b57f43a5ebddf71bc73685bdd6 100644
--- a/lib/util/fs/index.ts
+++ b/lib/util/fs/index.ts
@@ -6,7 +6,6 @@ import fs from 'fs-extra';
 import upath from 'upath';
 import { GlobalConfig } from '../../config/global';
 import { logger } from '../../logger';
-import { getFile } from '../git';
 import { ensureCachePath, ensureLocalPath } from './util';
 
 export const pipeline = util.promisify(stream.pipeline);
@@ -287,16 +286,13 @@ export function readSystemFile(
   return encoding ? fs.readFile(fileName, encoding) : fs.readFile(fileName);
 }
 
-export async function getFileContentMap(
-  fileNames: string[],
-  local = false
+export async function getLocalFiles(
+  fileNames: string[]
 ): Promise<Record<string, string | null>> {
   const fileContentMap: Record<string, string | null> = {};
 
   for (const fileName of fileNames) {
-    fileContentMap[fileName] = local
-      ? await readLocalFile(fileName, 'utf8')
-      : await getFile(fileName);
+    fileContentMap[fileName] = await readLocalFile(fileName, 'utf8');
   }
 
   return fileContentMap;
diff --git a/lib/util/git/index.spec.ts b/lib/util/git/index.spec.ts
index 459e4b99445a7f96ccc7737ece63dc2e46ce714a..239bb5b39faf04fef9206ce1a85b1d55008e3126 100644
--- a/lib/util/git/index.spec.ts
+++ b/lib/util/git/index.spec.ts
@@ -385,6 +385,16 @@ describe('util/git/index', () => {
     });
   });
 
+  describe('getFiles(filePath)', () => {
+    it('gets the file', async () => {
+      const res = await git.getFiles(['master_file', 'some_missing_path']);
+      expect(res).toEqual({
+        master_file: defaultBranch,
+        some_missing_path: null,
+      });
+    });
+  });
+
   describe('hasDiff(sourceRef, targetRef)', () => {
     it('compare without changes', () => {
       return expect(git.hasDiff('HEAD', 'HEAD')).resolves.toBeFalse();
diff --git a/lib/util/git/index.ts b/lib/util/git/index.ts
index 365b2beaed444b8bfaf316f5f1406139df346237..d74941ecea7e6f7f54ef36f1e679fa1de9de3a00 100644
--- a/lib/util/git/index.ts
+++ b/lib/util/git/index.ts
@@ -857,6 +857,18 @@ export async function getFile(
   }
 }
 
+export async function getFiles(
+  fileNames: string[]
+): Promise<Record<string, string | null>> {
+  const fileContentMap: Record<string, string | null> = {};
+
+  for (const fileName of fileNames) {
+    fileContentMap[fileName] = await getFile(fileName);
+  }
+
+  return fileContentMap;
+}
+
 export async function hasDiff(
   sourceRef: string,
   targetRef: string
diff --git a/lib/util/string.ts b/lib/util/string.ts
index 2ef7ae661d3b978a6496011022f2c36709306f19..4030956cdd923c62f3021b18003a3289761756c0 100644
--- a/lib/util/string.ts
+++ b/lib/util/string.ts
@@ -1,5 +1,3 @@
-import { logger } from '../logger';
-
 // Return true if the match string is found at index in content
 export function matchAt(
   content: string,
@@ -16,7 +14,6 @@ export function replaceAt(
   oldString: string,
   newString: string
 ): string {
-  logger.trace(`Replacing ${oldString} with ${newString} at index ${index}`);
   return (
     content.substring(0, index) +
     newString +