-
Notifications
You must be signed in to change notification settings - Fork 5.4k
fix(server): explain switchRef checkout failures with the fix to try next #9378
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -443,6 +443,27 @@ function isMissingWorktreeStderr(stderr: string): boolean { | |
| ); | ||
| } | ||
|
|
||
| // Classifies `git checkout` stderr into a closed set of static sentences. | ||
| // Raw stderr never leaves the driver (it can carry remote URLs with embedded | ||
| // credentials), so every branch returns a fixed string that names the cause | ||
| // and the fix instead of echoing git's output. | ||
| function classifySwitchRefCheckoutError(stderr: string): string { | ||
| const normalized = stderr.toLowerCase(); | ||
| if (normalized.includes("used by worktree")) { | ||
| return "git checkout failed because the branch is already checked out in another worktree. Switch in that worktree or check out a different branch."; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worktree matcher misses older GitMedium Severity
Reviewed by Cursor Bugbot for commit 71f3b27. Configure here. |
||
| } | ||
| if ( | ||
| normalized.includes("would be overwritten by checkout") || | ||
| normalized.includes("stash them before you switch") | ||
| ) { | ||
| return "git checkout failed because uncommitted changes would be overwritten. Commit, stash, or discard those changes, then try again."; | ||
| } | ||
| if (normalized.includes("did not match any file") || normalized.includes("pathspec")) { | ||
| return "git checkout failed because the ref was not found locally or on remotes. Fetch the latest refs and check the branch name, then try again."; | ||
| } | ||
| return "git checkout failed"; | ||
| } | ||
|
|
||
| interface Trace2Monitor { | ||
| readonly env: NodeJS.ProcessEnv; | ||
| readonly flush: Effect.Effect<void, never>; | ||
|
|
@@ -3207,10 +3228,33 @@ export const makeGitVcsDriverCore = Effect.fn("makeGitVcsDriverCore")(function* | |
| ? ["checkout", localTrackingBranch] | ||
| : ["checkout", input.refName]; | ||
|
|
||
| yield* executeGit("GitVcsDriver.switchRef.checkout", input.cwd, checkoutArgs, { | ||
| timeoutMs: 10_000, | ||
| fallbackErrorDetail: "git checkout failed", | ||
| }); | ||
| const checkoutResult = yield* executeGit( | ||
| "GitVcsDriver.switchRef.checkout", | ||
| input.cwd, | ||
| checkoutArgs, | ||
| { | ||
| timeoutMs: 10_000, | ||
| allowNonZeroExit: true, | ||
| }, | ||
| ); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Classifier skips stable Git localeMedium Severity
Additional Locations (1)Reviewed by Cursor Bugbot for commit 71f3b27. Configure here. |
||
| if (checkoutResult.exitCode !== 0) { | ||
| // Raw stderr stays out of the wire error (it can carry secrets); the | ||
| // classified detail names the cause and the fix instead. | ||
| yield* Effect.logWarning( | ||
| `GitVcsDriver.switchRef: git checkout exited with code ${checkoutResult.exitCode} (stderr length ${checkoutResult.stderr.length}).`, | ||
| ); | ||
| return yield* new GitCommandError({ | ||
| ...gitCommandContext({ | ||
| operation: "GitVcsDriver.switchRef.checkout", | ||
| cwd: input.cwd, | ||
| args: checkoutArgs, | ||
| }), | ||
| detail: classifySwitchRefCheckoutError(checkoutResult.stderr), | ||
| ...(checkoutResult.exitCode === null ? {} : { exitCode: checkoutResult.exitCode }), | ||
| stdoutLength: checkoutResult.stdout.length, | ||
| stderrLength: checkoutResult.stderr.length, | ||
| }); | ||
| } | ||
|
|
||
| const refName = yield* runGitStdout("GitVcsDriver.switchRef.currentBranch", input.cwd, [ | ||
| "branch", | ||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 Medium
vcs/GitVcsDriverCore.ts:451switchRefreturns the genericgit checkout faileddetail for translated worktree, overwrite, and missing-path diagnostics, so users lose the specific remediation this classifier is intended to provide.classifySwitchRefCheckoutErroronly matches English substrings, whileswitchRefrunscheckoutthroughexecuteGitwithout forcingLC_ALL: "C"; useexecuteGitWithStableDiagnosticsor otherwise set that locale before parsing stderr.🤖 Copy this AI Prompt to have your agent fix this: