diff --git a/lib/modules/platform/github/index.spec.ts b/lib/modules/platform/github/index.spec.ts
index 9fac0812ddfa151a89e582bc01b9c9eb185d10ff..91d35bc7177cf7368cd668bf1381aa4c7024faa0 100644
--- a/lib/modules/platform/github/index.spec.ts
+++ b/lib/modules/platform/github/index.spec.ts
@@ -35,7 +35,6 @@ describe('modules/platform/github/index', () => {
 
     setBaseUrl(githubApiHost);
 
-    git.branchExists.mockReturnValue(true);
     git.isBranchBehindBase.mockResolvedValue(true);
     git.getBranchCommit.mockReturnValue(
       '0d9c7726c3d628b7e28af234595cfd20febdbf8e'
@@ -861,6 +860,8 @@ describe('modules/platform/github/index', () => {
             updated_at: '01-09-2022',
           },
         ])
+        .head('/repos/some/repo/git/refs/heads/somebranch')
+        .reply(404)
         .post('/repos/some/repo/git/refs')
         .reply(201)
         .patch('/repos/some/repo/pulls/91')
@@ -950,6 +951,8 @@ describe('modules/platform/github/index', () => {
             closed_at: DateTime.now().minus({ minutes: 10 }).toISO(),
           },
         ])
+        .head('/repos/some/repo/git/refs/heads/somebranch')
+        .reply(404)
         .post('/repos/some/repo/git/refs')
         .reply(201)
         .patch('/repos/some/repo/pulls/91')
@@ -976,7 +979,7 @@ describe('modules/platform/github/index', () => {
             closed_at: DateTime.now().minus({ minutes: 10 }).toISO(),
           },
         ])
-        .post('/repos/some/repo/git/refs')
+        .head('/repos/some/repo/git/refs/heads/somebranch')
         .reply(422);
 
       await github.initRepo({ repository: 'some/repo' });
@@ -3243,7 +3246,6 @@ describe('modules/platform/github/index', () => {
     it('commits and returns SHA string', async () => {
       git.pushCommitToRenovateRef.mockResolvedValueOnce();
       git.listCommitTree.mockResolvedValueOnce([]);
-      git.branchExists.mockReturnValueOnce(false);
 
       const scope = httpMock.scope(githubApiHost);
 
@@ -3255,6 +3257,8 @@ describe('modules/platform/github/index', () => {
         .reply(200, { sha: '111' })
         .post('/repos/some/repo/git/commits')
         .reply(200, { sha: '222' })
+        .head('/repos/some/repo/git/refs/heads/foo/bar')
+        .reply(404)
         .post('/repos/some/repo/git/refs')
         .reply(200);
 
@@ -3270,7 +3274,6 @@ describe('modules/platform/github/index', () => {
     it('performs rebase', async () => {
       git.pushCommitToRenovateRef.mockResolvedValueOnce();
       git.listCommitTree.mockResolvedValueOnce([]);
-      git.branchExists.mockReturnValueOnce(true);
 
       const scope = httpMock.scope(githubApiHost);
 
@@ -3282,6 +3285,8 @@ describe('modules/platform/github/index', () => {
         .reply(200, { sha: '111' })
         .post('/repos/some/repo/git/commits')
         .reply(200, { sha: '222' })
+        .head('/repos/some/repo/git/refs/heads/foo/bar')
+        .reply(200)
         .patch('/repos/some/repo/git/refs/heads/foo/bar')
         .reply(200);
 
diff --git a/lib/modules/platform/github/index.ts b/lib/modules/platform/github/index.ts
index 7c9ac146a375bce2c1654bca45e52b1cc063a8cf..ffc5f1ab893144afd68eff0042fe78a670689002 100644
--- a/lib/modules/platform/github/index.ts
+++ b/lib/modules/platform/github/index.ts
@@ -742,6 +742,29 @@ export async function findPr({
 
 const REOPEN_THRESHOLD_MILLIS = 1000 * 60 * 60 * 24 * 7;
 
+async function ensureBranchSha(branchName: string, sha: string): Promise<void> {
+  const refUrl = `/repos/${config.repository}/git/refs/heads/${branchName}`;
+
+  let branchExists = false;
+  try {
+    await githubApi.head(refUrl, { useCache: false });
+    branchExists = true;
+  } catch (err) {
+    if (err.statusCode !== 404) {
+      throw err;
+    }
+  }
+
+  if (branchExists) {
+    await githubApi.patchJson(refUrl, { body: { sha, force: true } });
+    return;
+  }
+
+  await githubApi.postJson(`/repos/${config.repository}/git/refs`, {
+    body: { sha, ref: `refs/heads/${branchName}` },
+  });
+}
+
 // Returns the Pull Request for a branch. Null if not exists.
 export async function getBranchPr(branchName: string): Promise<GhPr | null> {
   logger.debug(`getBranchPr(${branchName})`);
@@ -776,9 +799,7 @@ export async function getBranchPr(branchName: string): Promise<GhPr | null> {
     }
     const { sha, number } = autoclosedPr;
     try {
-      await githubApi.postJson(`repos/${config.repository}/git/refs`, {
-        body: { ref: `refs/heads/${branchName}`, sha },
-      });
+      await ensureBranchSha(branchName, sha!);
       logger.debug(`Recreated autoclosed branch ${branchName} with sha ${sha}`);
     } catch (err) {
       logger.debug('Could not recreate autoclosed branch - skipping reopen');
@@ -1794,21 +1815,7 @@ async function pushFiles(
       { body: { message, tree: treeSha, parents: [parentCommitSha] } }
     );
     const remoteCommitSha = commitRes.body.sha;
-
-    // Create branch if it didn't already exist, update it otherwise
-    if (git.branchExists(branchName)) {
-      // This is the equivalent of a git force push
-      // We are using this REST API because the GraphQL API doesn't support force push
-      await githubApi.patchJson(
-        `/repos/${config.repository}/git/refs/heads/${branchName}`,
-        { body: { sha: remoteCommitSha, force: true } }
-      );
-    } else {
-      await githubApi.postJson(`/repos/${config.repository}/git/refs`, {
-        body: { ref: `refs/heads/${branchName}`, sha: remoteCommitSha },
-      });
-    }
-
+    await ensureBranchSha(branchName, remoteCommitSha);
     return remoteCommitSha;
   } catch (err) {
     logger.debug({ branchName, err }, 'Platform-native commit: unknown error');