From 6136cd0e04858ccc33532ade383bcd5ec8f4bba2 Mon Sep 17 00:00:00 2001 From: James Gatz Date: Wed, 22 Apr 2026 10:47:33 +0200 Subject: [PATCH] fix: handle detached HEAD during rebase in getCurrentBranch method (#9843) * fix: handle detached HEAD during rebase in getCurrentBranch method * fix: add return type to getCurrentBranch method --- packages/insomnia/src/sync/git/git-vcs.ts | 28 +++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/packages/insomnia/src/sync/git/git-vcs.ts b/packages/insomnia/src/sync/git/git-vcs.ts index e0e246cda8..6eeed8590d 100644 --- a/packages/insomnia/src/sync/git/git-vcs.ts +++ b/packages/insomnia/src/sync/git/git-vcs.ts @@ -240,14 +240,34 @@ export class GitVCS { return this._baseOpts.repoId === id; } - async getCurrentBranch() { + async getCurrentBranch(): Promise { const branch = await git.currentBranch({ ...this._baseOpts }); - if (typeof branch !== 'string') { - throw new TypeError('No active branch'); + if (typeof branch === 'string') { + return branch; } - return branch; + // During a rebase, HEAD can be detached and currentBranch() returns undefined. + // In that case, Git stores the original branch ref in rebase metadata. + const gitDir = this._baseOpts.gitdir || path.join(this._baseOpts.dir, gitInternalDirName); + const rebaseHeadNamePaths = [ + path.join(gitDir, 'rebase-merge', 'head-name'), + path.join(gitDir, 'rebase-apply', 'head-name'), + ]; + + for (const headNamePath of rebaseHeadNamePaths) { + try { + assertIsPromiseFsClient(this._baseOpts.fs); + const headName = (await this._baseOpts.fs.promises.readFile(headNamePath, 'utf8')).trim(); + if (headName.startsWith('refs/heads/')) { + return headName.replace('refs/heads/', ''); + } + } catch { + // Ignore and try the next known rebase metadata path. + } + } + + throw new TypeError('No active branch'); } async listBranches() {