| ... | ... | @@ -194,15 +194,19 @@ describe("git integration", () => { |
| 194 | 194 | // ── createGitWorktree + removeGitWorktree ── |
| 195 | 195 | |
| 196 | 196 | describe("createGitWorktree", () => { |
| 197 | | it("creates a worktree directory at the expected path", async () => { |
| 197 | it("creates a worktree with a new branch from the base branch", async () => { |
| 198 | 198 | await using tmp = await makeTmpDir(); |
| 199 | 199 | await initRepoWithCommit(tmp.path); |
| 200 | | await createGitBranch({ cwd: tmp.path, branch: "wt-branch" }); |
| 201 | 200 | |
| 202 | 201 | const wtPath = path.join(tmp.path, "worktree-out"); |
| 202 | const currentBranch = (await listGitBranches({ cwd: tmp.path })).branches.find( |
| 203 | (b) => b.current, |
| 204 | )!.name; |
| 205 | |
| 203 | 206 | const result = await createGitWorktree({ |
| 204 | 207 | cwd: tmp.path, |
| 205 | | branch: "wt-branch", |
| 208 | branch: currentBranch, |
| 209 | newBranch: "wt-branch", |
| 206 | 210 | path: wtPath, |
| 207 | 211 | }); |
| 208 | 212 | |
| ... | ... | @@ -215,37 +219,44 @@ describe("git integration", () => { |
| 215 | 219 | await removeGitWorktree({ cwd: tmp.path, path: wtPath }); |
| 216 | 220 | }); |
| 217 | 221 | |
| 218 | | it("worktree has the correct branch checked out", async () => { |
| 222 | it("worktree has the new branch checked out", async () => { |
| 219 | 223 | await using tmp = await makeTmpDir(); |
| 220 | 224 | await initRepoWithCommit(tmp.path); |
| 221 | | await createGitBranch({ cwd: tmp.path, branch: "wt-check" }); |
| 222 | 225 | |
| 223 | 226 | const wtPath = path.join(tmp.path, "wt-check-dir"); |
| 227 | const currentBranch = (await listGitBranches({ cwd: tmp.path })).branches.find( |
| 228 | (b) => b.current, |
| 229 | )!.name; |
| 230 | |
| 224 | 231 | await createGitWorktree({ |
| 225 | 232 | cwd: tmp.path, |
| 226 | | branch: "wt-check", |
| 233 | branch: currentBranch, |
| 234 | newBranch: "wt-check", |
| 227 | 235 | path: wtPath, |
| 228 | 236 | }); |
| 229 | 237 | |
| 230 | | // Verify the worktree is on the right branch |
| 238 | // Verify the worktree is on the new branch |
| 231 | 239 | const branchOutput = await git(wtPath, "branch --show-current"); |
| 232 | 240 | expect(branchOutput).toBe("wt-check"); |
| 233 | 241 | |
| 234 | 242 | await removeGitWorktree({ cwd: tmp.path, path: wtPath }); |
| 235 | 243 | }); |
| 236 | 244 | |
| 237 | | it("throws when branch is already checked out in main worktree", async () => { |
| 245 | it("throws when new branch name already exists", async () => { |
| 238 | 246 | await using tmp = await makeTmpDir(); |
| 239 | 247 | await initRepoWithCommit(tmp.path); |
| 240 | | // Try to create a worktree for the current branch (already checked out) |
| 241 | | const branches = await listGitBranches({ cwd: tmp.path }); |
| 242 | | const currentBranch = branches.branches.find((b) => b.current)!.name; |
| 248 | await createGitBranch({ cwd: tmp.path, branch: "existing" }); |
| 243 | 249 | |
| 244 | 250 | const wtPath = path.join(tmp.path, "wt-conflict"); |
| 251 | const currentBranch = (await listGitBranches({ cwd: tmp.path })).branches.find( |
| 252 | (b) => b.current, |
| 253 | )!.name; |
| 254 | |
| 245 | 255 | await expect( |
| 246 | 256 | createGitWorktree({ |
| 247 | 257 | cwd: tmp.path, |
| 248 | 258 | branch: currentBranch, |
| 259 | newBranch: "existing", |
| 249 | 260 | path: wtPath, |
| 250 | 261 | }), |
| 251 | 262 | ).rejects.toThrow(); |
| ... | ... | @@ -254,12 +265,16 @@ describe("git integration", () => { |
| 254 | 265 | it("removeGitWorktree cleans up the worktree", async () => { |
| 255 | 266 | await using tmp = await makeTmpDir(); |
| 256 | 267 | await initRepoWithCommit(tmp.path); |
| 257 | | await createGitBranch({ cwd: tmp.path, branch: "wt-remove" }); |
| 258 | 268 | |
| 259 | 269 | const wtPath = path.join(tmp.path, "wt-remove-dir"); |
| 270 | const currentBranch = (await listGitBranches({ cwd: tmp.path })).branches.find( |
| 271 | (b) => b.current, |
| 272 | )!.name; |
| 273 | |
| 260 | 274 | await createGitWorktree({ |
| 261 | 275 | cwd: tmp.path, |
| 262 | | branch: "wt-remove", |
| 276 | branch: currentBranch, |
| 277 | newBranch: "wt-remove", |
| 263 | 278 | path: wtPath, |
| 264 | 279 | }); |
| 265 | 280 | expect(existsSync(wtPath)).toBe(true); |
| ... | ... | @@ -284,18 +299,22 @@ describe("git integration", () => { |
| 284 | 299 | }); |
| 285 | 300 | }); |
| 286 | 301 | |
| 287 | | // ── Full flow: worktree creation from selected branch ── |
| 302 | // ── Full flow: worktree creation from base branch ── |
| 288 | 303 | |
| 289 | 304 | describe("full flow: worktree creation", () => { |
| 290 | | it("creates worktree from a non-current branch", async () => { |
| 305 | it("creates worktree with new branch from current branch", async () => { |
| 291 | 306 | await using tmp = await makeTmpDir(); |
| 292 | 307 | await initRepoWithCommit(tmp.path); |
| 293 | | await createGitBranch({ cwd: tmp.path, branch: "feature-wt" }); |
| 308 | |
| 309 | const currentBranch = (await listGitBranches({ cwd: tmp.path })).branches.find( |
| 310 | (b) => b.current, |
| 311 | )!.name; |
| 294 | 312 | |
| 295 | 313 | const wtPath = path.join(tmp.path, "my-worktree"); |
| 296 | 314 | const result = await createGitWorktree({ |
| 297 | 315 | cwd: tmp.path, |
| 298 | | branch: "feature-wt", |
| 316 | branch: currentBranch, |
| 317 | newBranch: "feature-wt", |
| 299 | 318 | path: wtPath, |
| 300 | 319 | }); |
| 301 | 320 | |
| ... | ... | @@ -305,9 +324,9 @@ describe("git integration", () => { |
| 305 | 324 | // Main repo still on original branch |
| 306 | 325 | const mainBranches = await listGitBranches({ cwd: tmp.path }); |
| 307 | 326 | const mainCurrent = mainBranches.branches.find((b) => b.current); |
| 308 | | expect(mainCurrent!.name).not.toBe("feature-wt"); |
| 327 | expect(mainCurrent!.name).toBe(currentBranch); |
| 309 | 328 | |
| 310 | | // Worktree is on feature-wt |
| 329 | // Worktree is on the new branch |
| 311 | 330 | const wtBranch = await git(wtPath, "branch --show-current"); |
| 312 | 331 | expect(wtBranch).toBe("feature-wt"); |
| 313 | 332 | |
| ... | ... | @@ -356,7 +375,9 @@ describe("git integration", () => { |
| 356 | 375 | await git(tmp.path, "commit -m 'diverge'"); |
| 357 | 376 | |
| 358 | 377 | // Go back to default branch |
| 359 | | const defaultBranch = (await git(tmp.path, "rev-parse --abbrev-ref HEAD")).includes("diverged") |
| 378 | const defaultBranch = (await git(tmp.path, "rev-parse --abbrev-ref HEAD")).includes( |
| 379 | "diverged", |
| 380 | ) |
| 360 | 381 | ? // we're on diverged, need to find the other one |
| 361 | 382 | (await listGitBranches({ cwd: tmp.path })).branches.find( |
| 362 | 383 | (b) => !b.current && b.name !== "diverged", |