diff --git a/lib/util/cache/branch/index.ts b/lib/util/cache/branch/index.ts
deleted file mode 100644
index fff97b1f61f398ed41840223526da335db57257b..0000000000000000000000000000000000000000
--- a/lib/util/cache/branch/index.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-export {
-  deleteCachedBranchParentShaResult,
-  getCachedBranchParentShaResult,
-} from './parent-sha';
-export { setBranchNewCommit } from './set-branch-commit';
-export {
-  getCachedBehindBaseResult,
-  setCachedBehindBaseResult,
-} from './behind-base-branch';
-export { getCachedConflictResult, setCachedConflictResult } from './conflict';
-export { getCachedModifiedResult, setCachedModifiedResult } from './modified';
diff --git a/lib/util/cache/branch/behind-base-branch.spec.ts b/lib/util/git/behind-base-branch-cache.spec.ts
similarity index 95%
rename from lib/util/cache/branch/behind-base-branch.spec.ts
rename to lib/util/git/behind-base-branch-cache.spec.ts
index da54478eb70bbb6758644bcbb7c93ad7f2270ea7..4aaabc6aaaaa2436f64da9f510f5fa661ca554e3 100644
--- a/lib/util/cache/branch/behind-base-branch.spec.ts
+++ b/lib/util/git/behind-base-branch-cache.spec.ts
@@ -1,15 +1,15 @@
-import { logger, mocked, partial } from '../../../../test/util';
-import * as _repositoryCache from '../repository';
-import type { BranchCache, RepoCacheData } from '../repository/types';
+import { logger, mocked, partial } from '../../../test/util';
+import * as _repositoryCache from '../cache/repository';
+import type { BranchCache, RepoCacheData } from '../cache/repository/types';
 import {
   getCachedBehindBaseResult,
   setCachedBehindBaseResult,
-} from './behind-base-branch';
+} from './behind-base-branch-cache';
 
-jest.mock('../repository');
+jest.mock('../cache/repository');
 const repositoryCache = mocked(_repositoryCache);
 
-describe('util/cache/branch/behind-base-branch', () => {
+describe('util/git/behind-base-branch-cache', () => {
   let repoCache: RepoCacheData = {};
 
   beforeEach(() => {
diff --git a/lib/util/cache/branch/behind-base-branch.ts b/lib/util/git/behind-base-branch-cache.ts
similarity index 91%
rename from lib/util/cache/branch/behind-base-branch.ts
rename to lib/util/git/behind-base-branch-cache.ts
index 3b0846cd890238ad8d4d787be553a30e7d316761..929457a8a5ce3d897ce29943d98eb8740c0edcf5 100644
--- a/lib/util/cache/branch/behind-base-branch.ts
+++ b/lib/util/git/behind-base-branch-cache.ts
@@ -1,5 +1,5 @@
-import { logger } from '../../../logger';
-import { getCache } from '../repository';
+import { logger } from '../../logger';
+import { getCache } from '../cache/repository';
 
 export function getCachedBehindBaseResult(
   branchName: string,
diff --git a/lib/util/cache/branch/conflict.spec.ts b/lib/util/git/conflicts-cache.spec.ts
similarity index 92%
rename from lib/util/cache/branch/conflict.spec.ts
rename to lib/util/git/conflicts-cache.spec.ts
index 4b456e5dbf70e99a2d8bfb402907a810da5d026f..745d49405557e2b075155af3ae7d4d01e46609df 100644
--- a/lib/util/cache/branch/conflict.spec.ts
+++ b/lib/util/git/conflicts-cache.spec.ts
@@ -1,12 +1,15 @@
-import { mocked, partial } from '../../../../test/util';
-import * as _repositoryCache from '../repository';
-import type { BranchCache, RepoCacheData } from '../repository/types';
-import { getCachedConflictResult, setCachedConflictResult } from './conflict';
+import { mocked, partial } from '../../../test/util';
+import * as _repositoryCache from '../cache/repository';
+import type { BranchCache, RepoCacheData } from '../cache/repository/types';
+import {
+  getCachedConflictResult,
+  setCachedConflictResult,
+} from './conflicts-cache';
 
-jest.mock('../repository');
+jest.mock('../cache/repository');
 const repositoryCache = mocked(_repositoryCache);
 
-describe('util/cache/branch/conflict', () => {
+describe('util/git/conflicts-cache', () => {
   let repoCache: RepoCacheData = {};
 
   beforeEach(() => {
diff --git a/lib/util/cache/branch/conflict.ts b/lib/util/git/conflicts-cache.ts
similarity index 91%
rename from lib/util/cache/branch/conflict.ts
rename to lib/util/git/conflicts-cache.ts
index 53826e398763775e7b6c7a774327c7b4d5888b6a..89644332a30fbdde79031a7bb19fa05f5463deee 100644
--- a/lib/util/cache/branch/conflict.ts
+++ b/lib/util/git/conflicts-cache.ts
@@ -1,5 +1,5 @@
-import { logger } from '../../../logger';
-import { getCache } from '../repository';
+import { logger } from '../../logger';
+import { getCache } from '../cache/repository';
 
 export function getCachedConflictResult(
   branchName: string,
diff --git a/lib/util/git/index.spec.ts b/lib/util/git/index.spec.ts
index 3a82239e7bebae5206d6432ccba3134621d9a4ce..d5548cbd4a566bbbb418bca393d0fb2f9c6f5e23 100644
--- a/lib/util/git/index.spec.ts
+++ b/lib/util/git/index.spec.ts
@@ -7,17 +7,25 @@ import {
   CONFIG_VALIDATION,
   INVALID_PATH,
 } from '../../constants/error-messages';
-import * as _branchCache from '../cache/branch';
 import { newlineRegex, regEx } from '../regex';
+import * as _behindBaseCache from './behind-base-branch-cache';
+import * as _conflictsCache from './conflicts-cache';
+import * as _modifiedCache from './modified-cache';
+import * as _parentShaCache from './parent-sha-cache';
 import type { FileChange } from './types';
 import * as git from '.';
 import { setNoVerify } from '.';
 
-jest.mock('../cache/branch');
+jest.mock('./conflicts-cache');
+jest.mock('./behind-base-branch-cache');
+jest.mock('./modified-cache');
+jest.mock('./parent-sha-cache');
 jest.mock('delay');
 jest.mock('../cache/repository');
-const branchCache = mocked(_branchCache);
-
+const behindBaseCache = mocked(_behindBaseCache);
+const conflictsCache = mocked(_conflictsCache);
+const modifiedCache = mocked(_modifiedCache);
+const parentShaCache = mocked(_parentShaCache);
 // Class is no longer exported
 const SimpleGit = Git().constructor as { prototype: ReturnType<typeof Git> };
 
@@ -108,8 +116,8 @@ describe('util/git/index', () => {
     // override some local git settings for better testing
     const local = Git(tmpDir.path);
     await local.addConfig('commit.gpgsign', 'false');
-    branchCache.getCachedBranchParentShaResult.mockReturnValue(null);
-    branchCache.getCachedBehindBaseResult.mockReturnValue(null);
+    parentShaCache.getCachedBranchParentShaResult.mockReturnValue(null);
+    behindBaseCache.getCachedBehindBaseResult.mockReturnValue(null);
   });
 
   afterEach(async () => {
@@ -256,7 +264,7 @@ describe('util/git/index', () => {
     });
 
     it('returns cached value', async () => {
-      branchCache.getCachedBehindBaseResult.mockReturnValue(true);
+      behindBaseCache.getCachedBehindBaseResult.mockReturnValue(true);
       expect(await git.isBranchBehindBase('develop', defaultBranch)).toBeTrue();
       expect(logger.logger.debug).toHaveBeenCalledWith(
         'branch.isBehindBase(): using cached result "true"'
@@ -266,7 +274,7 @@ describe('util/git/index', () => {
 
   describe('isBranchModified()', () => {
     beforeEach(() => {
-      branchCache.getCachedModifiedResult.mockReturnValue(null);
+      modifiedCache.getCachedModifiedResult.mockReturnValue(null);
     });
 
     it('should return false when branch is not found', async () => {
@@ -290,7 +298,7 @@ describe('util/git/index', () => {
     });
 
     it('should return value stored in modifiedCacheResult', async () => {
-      branchCache.getCachedModifiedResult.mockReturnValue(true);
+      modifiedCache.getCachedModifiedResult.mockReturnValue(true);
       expect(await git.isBranchModified('renovate/future_branch')).toBeTrue();
     });
   });
@@ -797,7 +805,7 @@ describe('util/git/index', () => {
 
       await repo.checkout(defaultBranch);
 
-      branchCache.getCachedConflictResult.mockReturnValue(null);
+      conflictsCache.getCachedConflictResult.mockReturnValue(null);
     });
 
     it('returns true for non-existing source branch', async () => {
@@ -854,7 +862,7 @@ describe('util/git/index', () => {
       });
 
       it('returns cached values', async () => {
-        branchCache.getCachedConflictResult.mockReturnValue(true);
+        conflictsCache.getCachedConflictResult.mockReturnValue(true);
 
         const res = await git.isBranchConflicted(
           defaultBranch,
@@ -862,7 +870,7 @@ describe('util/git/index', () => {
         );
 
         expect(res).toBeTrue();
-        expect(branchCache.getCachedConflictResult.mock.calls).toEqual([
+        expect(conflictsCache.getCachedConflictResult.mock.calls).toEqual([
           [
             'renovate/conflicted_branch',
             git.getBranchCommit('renovate/conflicted_branch'),
@@ -870,11 +878,11 @@ describe('util/git/index', () => {
             git.getBranchCommit(defaultBranch),
           ],
         ]);
-        expect(branchCache.setCachedConflictResult).not.toHaveBeenCalled();
+        expect(conflictsCache.setCachedConflictResult).not.toHaveBeenCalled();
       });
 
       it('caches truthy return value', async () => {
-        branchCache.getCachedConflictResult.mockReturnValue(null);
+        conflictsCache.getCachedConflictResult.mockReturnValue(null);
 
         const res = await git.isBranchConflicted(
           defaultBranch,
@@ -882,13 +890,13 @@ describe('util/git/index', () => {
         );
 
         expect(res).toBeTrue();
-        expect(branchCache.setCachedConflictResult.mock.calls).toEqual([
+        expect(conflictsCache.setCachedConflictResult.mock.calls).toEqual([
           ['renovate/conflicted_branch', true],
         ]);
       });
 
       it('caches falsy return value', async () => {
-        branchCache.getCachedConflictResult.mockReturnValue(null);
+        conflictsCache.getCachedConflictResult.mockReturnValue(null);
 
         const res = await git.isBranchConflicted(
           defaultBranch,
@@ -896,7 +904,7 @@ describe('util/git/index', () => {
         );
 
         expect(res).toBeFalse();
-        expect(branchCache.setCachedConflictResult.mock.calls).toEqual([
+        expect(conflictsCache.setCachedConflictResult.mock.calls).toEqual([
           ['renovate/non_conflicted_branch', false],
         ]);
       });
diff --git a/lib/util/git/index.ts b/lib/util/git/index.ts
index 86525d10bd5e61b0e8468627925627f28c7ad9d8..2a6b95d9b31f5f3e84ed184732615f2c30b066ab 100644
--- a/lib/util/git/index.ts
+++ b/lib/util/git/index.ts
@@ -28,22 +28,24 @@ import { api as semverCoerced } from '../../modules/versioning/semver-coerced';
 import { ExternalHostError } from '../../types/errors/external-host-error';
 import type { GitProtocol } from '../../types/git';
 import { Limit, incLimitedValue } from '../../workers/global/limits';
-import {
-  deleteCachedBranchParentShaResult,
-  getCachedBehindBaseResult,
-  getCachedConflictResult,
-  getCachedModifiedResult,
-  setCachedConflictResult,
-  setCachedModifiedResult,
-} from '../cache/branch';
 import { newlineRegex, regEx } from '../regex';
 import { parseGitAuthor } from './author';
+import { getCachedBehindBaseResult } from './behind-base-branch-cache';
 import { getNoVerify, simpleGitConfig } from './config';
+import {
+  getCachedConflictResult,
+  setCachedConflictResult,
+} from './conflicts-cache';
 import {
   bulkChangesDisallowed,
   checkForPlatformFailure,
   handleCommitError,
 } from './error';
+import {
+  getCachedModifiedResult,
+  setCachedModifiedResult,
+} from './modified-cache';
+import { deleteCachedBranchParentShaResult } from './parent-sha-cache';
 import { configSigningKey, writePrivateKey } from './private-key';
 import type {
   CommitFilesConfig,
diff --git a/lib/util/cache/branch/modified.spec.ts b/lib/util/git/modified-cache.spec.ts
similarity index 90%
rename from lib/util/cache/branch/modified.spec.ts
rename to lib/util/git/modified-cache.spec.ts
index 3d67df480754fce8c1923a2972c1383d6f4c2fd6..75ab80d203e4d551d4a23065b5bd093767dfd7c3 100644
--- a/lib/util/cache/branch/modified.spec.ts
+++ b/lib/util/git/modified-cache.spec.ts
@@ -1,12 +1,15 @@
-import { logger, mocked, partial } from '../../../../test/util';
-import * as _repositoryCache from '../repository';
-import type { BranchCache, RepoCacheData } from '../repository/types';
-import { getCachedModifiedResult, setCachedModifiedResult } from './modified';
+import { logger, mocked, partial } from '../../../test/util';
+import * as _repositoryCache from '../cache/repository';
+import type { BranchCache, RepoCacheData } from '../cache/repository/types';
+import {
+  getCachedModifiedResult,
+  setCachedModifiedResult,
+} from './modified-cache';
 
-jest.mock('../repository');
+jest.mock('../cache/repository');
 const repositoryCache = mocked(_repositoryCache);
 
-describe('util/cache/branch/modified', () => {
+describe('util/git/modified-cache', () => {
   let repoCache: RepoCacheData = {};
 
   beforeEach(() => {
diff --git a/lib/util/cache/branch/modified.ts b/lib/util/git/modified-cache.ts
similarity index 89%
rename from lib/util/cache/branch/modified.ts
rename to lib/util/git/modified-cache.ts
index d6b405871ceb04fe03ff43c6e2d3c357a27af5ae..e25998cdd46e30b7d5317484fd5347ff2d9b5f8d 100644
--- a/lib/util/cache/branch/modified.ts
+++ b/lib/util/git/modified-cache.ts
@@ -1,5 +1,5 @@
-import { logger } from '../../../logger';
-import { getCache } from '../repository';
+import { logger } from '../../logger';
+import { getCache } from '../cache/repository';
 
 export function getCachedModifiedResult(
   branchName: string,
diff --git a/lib/util/cache/branch/parent-sha.spec.ts b/lib/util/git/parent-sha-cache.spec.ts
similarity index 88%
rename from lib/util/cache/branch/parent-sha.spec.ts
rename to lib/util/git/parent-sha-cache.spec.ts
index 760047226c8444aee8a904484b28b1818b508b4d..6c7f1abfd71cadc15916a50e7719bdb2d54b2907 100644
--- a/lib/util/cache/branch/parent-sha.spec.ts
+++ b/lib/util/git/parent-sha-cache.spec.ts
@@ -1,15 +1,15 @@
-import { mocked } from '../../../../test/util';
-import * as _repositoryCache from '../repository';
-import type { BranchCache, RepoCacheData } from '../repository/types';
+import { mocked } from '../../../test/util';
+import * as _repositoryCache from '../cache/repository';
+import type { BranchCache, RepoCacheData } from '../cache/repository/types';
 import {
   deleteCachedBranchParentShaResult,
   getCachedBranchParentShaResult,
-} from './parent-sha';
+} from './parent-sha-cache';
 
-jest.mock('../repository');
+jest.mock('../cache/repository');
 const repositoryCache = mocked(_repositoryCache);
 
-describe('util/cache/branch/parent-sha', () => {
+describe('util/git/parent-sha-cache', () => {
   let repoCache: RepoCacheData = {};
 
   beforeEach(() => {
diff --git a/lib/util/cache/branch/parent-sha.ts b/lib/util/git/parent-sha-cache.ts
similarity index 92%
rename from lib/util/cache/branch/parent-sha.ts
rename to lib/util/git/parent-sha-cache.ts
index facb298f25b791a812d9783f8e208f98135001a1..f5842c378057767127cafe74c1e5f425f4ac8f5d 100644
--- a/lib/util/cache/branch/parent-sha.ts
+++ b/lib/util/git/parent-sha-cache.ts
@@ -1,4 +1,4 @@
-import { getCache } from '../repository';
+import { getCache } from '../cache/repository';
 
 export function getCachedBranchParentShaResult(
   branchName: string,
diff --git a/lib/util/cache/branch/set-branch-commit.spec.ts b/lib/util/git/set-branch-commit.spec.ts
similarity index 86%
rename from lib/util/cache/branch/set-branch-commit.spec.ts
rename to lib/util/git/set-branch-commit.spec.ts
index 2b9dd62995945b71a22c701ccb1e3933fa0f026e..9518163e21cf57f38ddfd0c89aebbd2a2761089f 100644
--- a/lib/util/cache/branch/set-branch-commit.spec.ts
+++ b/lib/util/git/set-branch-commit.spec.ts
@@ -1,13 +1,13 @@
-import { git, logger, mocked, partial } from '../../../../test/util';
-import * as _repositoryCache from '../repository';
-import type { BranchCache, RepoCacheData } from '../repository/types';
+import { git, logger, mocked, partial } from '../../../test/util';
+import * as _repositoryCache from '../cache/repository';
+import type { BranchCache, RepoCacheData } from '../cache/repository/types';
 import { setBranchNewCommit } from './set-branch-commit';
 
-jest.mock('../repository');
-jest.mock('../../git');
+jest.mock('../cache/repository');
+jest.mock('.');
 const repositoryCache = mocked(_repositoryCache);
 
-describe('util/cache/branch/set-branch-commit', () => {
+describe('util/git/set-branch-commit', () => {
   let repoCache: RepoCacheData = {};
 
   beforeEach(() => {
diff --git a/lib/util/cache/branch/set-branch-commit.ts b/lib/util/git/set-branch-commit.ts
similarity index 81%
rename from lib/util/cache/branch/set-branch-commit.ts
rename to lib/util/git/set-branch-commit.ts
index fdd027c33ceeb806deee130869ff0f2e3371756d..c891469366667f0415e474fa9c812b72963d9b1e 100644
--- a/lib/util/cache/branch/set-branch-commit.ts
+++ b/lib/util/git/set-branch-commit.ts
@@ -1,7 +1,7 @@
-import { logger } from '../../../logger';
-import { getBranchCommit } from '../../git';
-import { getCache } from '../repository';
-import type { BranchCache } from '../repository/types';
+import { logger } from '../../logger';
+import { getCache } from '../cache/repository';
+import type { BranchCache } from '../cache/repository/types';
+import { getBranchCommit } from '.';
 
 /**
  * Called when a new commit is added to branch
diff --git a/lib/workers/repository/cache.ts b/lib/workers/repository/cache.ts
index 82f0af309372d9df56269bc46a2cabc49e432ebf..6de35aa19d4f80d8428349d419705cf11035833a 100644
--- a/lib/workers/repository/cache.ts
+++ b/lib/workers/repository/cache.ts
@@ -2,7 +2,6 @@
 
 import { logger } from '../../logger';
 import { platform } from '../../modules/platform';
-import { getCachedBranchParentShaResult } from '../../util/cache/branch';
 import { getCache } from '../../util/cache/repository';
 import type {
   BranchCache,
@@ -14,6 +13,7 @@ import {
   isBranchConflicted,
   isBranchModified,
 } from '../../util/git';
+import { getCachedBranchParentShaResult } from '../../util/git/parent-sha-cache';
 import type { BranchConfig, BranchUpgradeConfig } from '../types';
 
 function generateBranchUpgradeCache(
diff --git a/lib/workers/repository/process/write.ts b/lib/workers/repository/process/write.ts
index 69dca2425aca587bcf8a0713806f95cf55662892..e3f4d8cce0914e1da71c554183059785951dc261 100644
--- a/lib/workers/repository/process/write.ts
+++ b/lib/workers/repository/process/write.ts
@@ -2,11 +2,11 @@ import is from '@sindresorhus/is';
 import type { RenovateConfig } from '../../../config/types';
 import { addMeta, logger, removeMeta } from '../../../logger';
 import { hashMap } from '../../../modules/manager';
-import { setBranchNewCommit } from '../../../util/cache/branch';
 import { getCache } from '../../../util/cache/repository';
 import type { BranchCache } from '../../../util/cache/repository/types';
 import { fingerprint } from '../../../util/fingerprint';
 import { branchExists, getBranchCommit } from '../../../util/git';
+import { setBranchNewCommit } from '../../../util/git/set-branch-commit';
 import { Limit, incLimitedValue, setMaxLimit } from '../../global/limits';
 import {
   BranchConfig,