diff --git a/electron/ipc/git.ts b/electron/ipc/git.ts index 77068f2a..d2ad27eb 100644 --- a/electron/ipc/git.ts +++ b/electron/ipc/git.ts @@ -147,6 +147,18 @@ async function remoteTrackingRefExists(repoRoot: string, branch: string): Promis } } +/** Check whether a local branch ref exists. */ +async function localBranchExists(repoRoot: string, branch: string): Promise { + try { + await exec('git', ['rev-parse', '--verify', `refs/heads/${branch}`], { + cwd: repoRoot, + }); + return true; + } catch { + return false; + } +} + async function detectMainBranchUncached(repoRoot: string): Promise { // Try remote HEAD reference first const branch = await resolveOriginHead(repoRoot); @@ -168,10 +180,13 @@ async function detectMainBranchUncached(repoRoot: string): Promise { } } - // Check common default branch names + // Check common default branch names (remote-tracking first, then local) for (const candidate of ['main', 'master']) { if (await remoteTrackingRefExists(repoRoot, candidate)) return candidate; } + for (const candidate of ['main', 'master']) { + if (await localBranchExists(repoRoot, candidate)) return candidate; + } // Empty repo (no commits yet) — use configured default branch or fall back to "main" try { @@ -393,6 +408,26 @@ export async function createWorktree( } } + // Validate the start-point ref exists before attempting worktree creation + const startRef = baseBranch || 'HEAD'; + try { + await exec('git', ['rev-parse', '--verify', startRef], { cwd: repoRoot }); + } catch { + const isEmptyRepo = await exec('git', ['rev-list', '-n1', '--all'], { cwd: repoRoot }) + .then(({ stdout }) => !stdout.trim()) + .catch(() => true); + if (isEmptyRepo) { + throw new Error( + 'Cannot create a worktree in a repository with no commits. ' + + 'Please make an initial commit first.', + ); + } + throw new Error( + `Branch "${startRef}" does not exist. ` + + 'Please select a valid base branch or create the branch first.', + ); + } + // Create fresh worktree with new branch const worktreeArgs = ['worktree', 'add', '-b', branchName, worktreePath]; if (baseBranch) worktreeArgs.push(baseBranch);