Skip to content

fix(create): avoid following target symlinks - #2418

Draft
leslieeilsel wants to merge 1 commit into
voidzero-dev:mainfrom
leslieeilsel:agent/one-line-challenge
Draft

fix(create): avoid following target symlinks#2418
leslieeilsel wants to merge 1 commit into
voidzero-dev:mainfrom
leslieeilsel:agent/one-line-challenge

Conversation

@leslieeilsel

@leslieeilsel leslieeilsel commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Fixes #2419

Summary

  • classify the target entry with lstatSync instead of following the final symbolic link
  • identify symbolic links and other non-directory conflicts explicitly in the overwrite prompt
  • remove only the target link or file while preserving linked-directory contents
  • retain the existing cleanup behavior for real directories, including preserving .git

Root cause

The availability check used existsSync followed by readdirSync, so a directory symbolic link was treated as the directory it referenced. The cleanup loop then removed child paths through that link.

existsSync also treated dangling links as missing, while existing regular files reached directory-only operations.

Implementation

The target is now inspected with:

fs.lstatSync(targetPath, { throwIfNoEntry: false })

This keeps the final filesystem entry distinct from its destination:

  • a real empty directory remains immediately reusable
  • a real non-empty directory keeps the existing confirmation and cleanup behavior
  • a symbolic link receives an explicit “Remove symbolic link and continue” confirmation
  • confirmed links and regular files are removed as entries, without recursive traversal
  • dangling symbolic links are recognized as existing conflicts and can be removed safely

The cleanup function performs a fresh lstatSync immediately before mutation, so it also handles a target that disappears while the prompt is open.

Validation

  • vitest run packages/cli/src/create/__tests__: 13 files, 185 tests passed
  • tsc -p packages/cli/tsconfig.json --noEmit
  • targeted Vite+ lint and format checks
  • git diff --check

Regression coverage includes real directories, links to empty and populated directories, dangling links, regular files, linked-target preservation, and the existing .git preservation behavior.

@netlify

netlify Bot commented Aug 11, 2026

Copy link
Copy Markdown

Deploy Preview for viteplus-preview canceled.

Name Link
🔨 Latest commit 84ef107
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/6a7b3c9d05a4cb00080127e9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

create: overwrite follows target symlinks and deletes linked contents

1 participant