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