| ... | ... | @@ -739,13 +739,13 @@ it.layer(TestLayer)("GitVcsDriver core integration", (it) => { |
| 739 | 739 | Effect.gen(function* () { |
| 740 | 740 | const cwd = yield* makeTmpDir(); |
| 741 | 741 | const pathService = yield* Path.Path; |
| 742 | | const missingWorktree = pathService.join(cwd, "missing-worktree"); |
| 742 | const fileSystem = yield* FileSystem.FileSystem; |
| 743 | const notAWorktree = pathService.join(cwd, "not-a-worktree"); |
| 744 | yield* fileSystem.makeDirectory(notAWorktree); |
| 743 | 745 | const driver = yield* GitVcsDriver.GitVcsDriver; |
| 744 | 746 | yield* driver.initRepo({ cwd }); |
| 745 | 747 | |
| 746 | | const error = yield* driver |
| 747 | | .removeWorktree({ cwd, path: missingWorktree }) |
| 748 | | .pipe(Effect.flip); |
| 748 | const error = yield* driver.removeWorktree({ cwd, path: notAWorktree }).pipe(Effect.flip); |
| 749 | 749 | |
| 750 | 750 | assert.deepInclude(error, { |
| 751 | 751 | _tag: "GitCommandError", |
| ... | ... | @@ -755,9 +755,22 @@ it.layer(TestLayer)("GitVcsDriver core integration", (it) => { |
| 755 | 755 | cwd, |
| 756 | 756 | }); |
| 757 | 757 | assert.notProperty(error, "cause"); |
| 758 | assert.notProperty(error, "stderr"); |
| 758 | 759 | assert.notInclude(error.detail, "Git command failed in"); |
| 759 | 760 | }), |
| 760 | 761 | ); |
| 762 | |
| 763 | it.effect("treats removing an already-gone worktree as a no-op", () => |
| 764 | Effect.gen(function* () { |
| 765 | const cwd = yield* makeTmpDir(); |
| 766 | const pathService = yield* Path.Path; |
| 767 | const missingWorktree = pathService.join(cwd, "missing-worktree"); |
| 768 | const driver = yield* GitVcsDriver.GitVcsDriver; |
| 769 | yield* driver.initRepo({ cwd }); |
| 770 | |
| 771 | yield* driver.removeWorktree({ cwd, path: missingWorktree }); |
| 772 | }), |
| 773 | ); |
| 761 | 774 | }); |
| 762 | 775 | |
| 763 | 776 | describe("review diff previews", () => { |
| ... | ... | @@ -1487,6 +1500,57 @@ it.layer(TestLayer)("GitVcsDriver core integration", (it) => { |
| 1487 | 1500 | assert.equal(yield* fileSystem.exists(worktreePath), false); |
| 1488 | 1501 | }), |
| 1489 | 1502 | ); |
| 1503 | |
| 1504 | it.effect("removes the same worktree path twice without failing", () => |
| 1505 | Effect.gen(function* () { |
| 1506 | const cwd = yield* makeTmpDir(); |
| 1507 | const { initialBranch } = yield* initRepoWithCommit(cwd); |
| 1508 | const pathService = yield* Path.Path; |
| 1509 | const worktreePath = pathService.join(yield* makeTmpDir("git-worktrees-"), "shared"); |
| 1510 | const driver = yield* GitVcsDriver.GitVcsDriver; |
| 1511 | |
| 1512 | yield* driver.createWorktree({ |
| 1513 | cwd, |
| 1514 | path: worktreePath, |
| 1515 | refName: initialBranch, |
| 1516 | newRefName: "feature/shared", |
| 1517 | }); |
| 1518 | |
| 1519 | // Two threads can record the same worktree path; the second delete |
| 1520 | // must be a no-op instead of exit 128. |
| 1521 | yield* driver.removeWorktree({ cwd, path: worktreePath }); |
| 1522 | yield* driver.removeWorktree({ cwd, path: worktreePath }); |
| 1523 | }), |
| 1524 | ); |
| 1525 | |
| 1526 | it.effect("prunes stale registrations when removing an already-gone worktree", () => |
| 1527 | Effect.gen(function* () { |
| 1528 | const cwd = yield* makeTmpDir(); |
| 1529 | const { initialBranch } = yield* initRepoWithCommit(cwd); |
| 1530 | const pathService = yield* Path.Path; |
| 1531 | const fileSystem = yield* FileSystem.FileSystem; |
| 1532 | const worktreesRoot = yield* makeTmpDir("git-worktrees-"); |
| 1533 | const stalePath = pathService.join(worktreesRoot, "stale"); |
| 1534 | const driver = yield* GitVcsDriver.GitVcsDriver; |
| 1535 | |
| 1536 | yield* driver.createWorktree({ |
| 1537 | cwd, |
| 1538 | path: stalePath, |
| 1539 | refName: initialBranch, |
| 1540 | newRefName: "feature/stale", |
| 1541 | }); |
| 1542 | // Delete the directory behind git's back so the registration goes stale. |
| 1543 | yield* fileSystem.remove(stalePath, { recursive: true }); |
| 1544 | |
| 1545 | yield* driver.removeWorktree({ |
| 1546 | cwd, |
| 1547 | path: pathService.join(worktreesRoot, "never-registered"), |
| 1548 | }); |
| 1549 | |
| 1550 | const registered = yield* git(cwd, ["worktree", "list", "--porcelain"]); |
| 1551 | assert.notInclude(registered, "stale"); |
| 1552 | }), |
| 1553 | ); |
| 1490 | 1554 | }); |
| 1491 | 1555 | |
| 1492 | 1556 | describe("remote operations", () => { |