Skip to content

Commit 411160c

Browse files
committed
fix(scm): 🐛 avoid ambiguous commit workspace fallback
1 parent a203bb3 commit 411160c

2 files changed

Lines changed: 38 additions & 2 deletions

File tree

src/services/commit-message/CommitMessageProvider.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,15 @@ export class CommitMessageProvider implements vscode.Disposable {
205205
return resourceUri.fsPath
206206
}
207207

208-
const workspaceFolders = vscode.workspace.workspaceFolders
209-
if (workspaceFolders && workspaceFolders.length > 0) {
208+
const workspaceFolders = vscode.workspace.workspaceFolders ?? []
209+
if (workspaceFolders.length === 1) {
210210
return workspaceFolders[0].uri.fsPath
211211
}
212212

213+
if (workspaceFolders.length > 1) {
214+
throw new Error("Run this command from a specific Git source control input in a multi-root workspace")
215+
}
216+
213217
throw new Error("Could not determine workspace path")
214218
}
215219

src/services/commit-message/__tests__/CommitMessageProvider.spec.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ vi.mock("vscode", () => ({
77
window: {
88
showWarningMessage: vi.fn(),
99
},
10+
workspace: {
11+
workspaceFolders: undefined,
12+
},
13+
Uri: {
14+
file: (fsPath: string) => ({ fsPath }),
15+
},
1016
}))
1117

1218
describe("CommitMessageProvider", () => {
@@ -18,6 +24,7 @@ describe("CommitMessageProvider", () => {
1824

1925
beforeEach(() => {
2026
vi.clearAllMocks()
27+
;(vscode.workspace as any).workspaceFolders = undefined
2128
})
2229

2330
it("matches repository roots by path containment instead of string prefix", () => {
@@ -85,4 +92,29 @@ describe("CommitMessageProvider", () => {
8592
expect(gitCollector.gatherChanges).toHaveBeenCalledTimes(1)
8693
expect(resolution).toEqual({ changes: [], files: [], usedStaged: true })
8794
})
95+
96+
it("uses the SCM resource URI as the workspace path when provided", () => {
97+
const provider = createProvider()
98+
99+
expect((provider as any).determineWorkspacePath(vscode.Uri.file("/repo"))).toBe("/repo")
100+
})
101+
102+
it("falls back to the workspace folder only when exactly one folder is open", () => {
103+
;(vscode.workspace as any).workspaceFolders = [{ uri: vscode.Uri.file("/single-root") }]
104+
const provider = createProvider()
105+
106+
expect((provider as any).determineWorkspacePath()).toBe("/single-root")
107+
})
108+
109+
it("fails clearly instead of guessing in multi-root workspaces", () => {
110+
;(vscode.workspace as any).workspaceFolders = [
111+
{ uri: vscode.Uri.file("/first-root") },
112+
{ uri: vscode.Uri.file("/second-root") },
113+
]
114+
const provider = createProvider()
115+
116+
expect(() => (provider as any).determineWorkspacePath()).toThrow(
117+
"Run this command from a specific Git source control input in a multi-root workspace",
118+
)
119+
})
88120
})

0 commit comments

Comments
 (0)