Skip to content

Fix duplicate installs from sibling Git worktrees#1639

Open
StellaHuang95 wants to merge 1 commit into
microsoft:mainfrom
StellaHuang95:fix/1627-worktree-duplicate-install
Open

Fix duplicate installs from sibling Git worktrees#1639
StellaHuang95 wants to merge 1 commit into
microsoft:mainfrom
StellaHuang95:fix/1627-worktree-duplicate-install

Conversation

@StellaHuang95

Copy link
Copy Markdown
Contributor

Context

Fixes #1627.

Quick Create discovers workspace dependencies and installs local pyproject.toml projects in editable mode. When a workspace contains sibling Git worktrees such as:

myapp/
├── main/pyproject.toml       # [project].name = "myapp"
└── copilot/pyproject.toml    # [project].name = "myapp"

both files previously contributed editable arguments to the same resolver transaction:

pip install -e ./main -e ./copilot

pip and uv treat those paths as two sources for the same distribution and reject the request.

Changes

  • Read the PEP 621 [project].name from each discovered pyproject.toml.
  • Normalize distribution names using PEP 503 rules, so spellings such as My_App, my.app, and my-app are treated as the same package.
  • Add an opt-in automatic-install mode that keeps at most one editable source per normalized distribution name.
  • Prefer the candidate whose project directory contains the environment creation root; when nested candidates match, prefer the deepest candidate.
  • Avoid choosing an arbitrary sibling when no candidate contains the creation root.
  • Enable the behavior in both venv Quick Create paths while leaving the custom/manual package picker unchanged.
  • Parse TOMLs first and emit results deterministically, so candidate selection and validation do not depend on file-read completion order.
  • Validate the selected TOML rather than surfacing metadata errors from a rejected worktree.

Result

When Quick Create targets a specific worktree, only that checkout is installed:

pip install -e ./main

Distinct distributions in a normal monorepo remain installable together, and single-project workspaces keep their existing behavior.

Scope and known limitations

  • If Quick Create targets the common parent of sibling same-name worktrees, neither child contains the creation root. The implementation deliberately skips all ambiguous editable sources instead of guessing. The environment is created without either local project, and the omission is currently reported only in the extension log.
  • Deduplication applies to editable installables derived from PEP 621 pyproject.toml metadata. Requirements files remain unchanged and worktree-unscoped; conflicting sibling requirements.txt files, or requirements that themselves contain duplicate editable paths, can still conflict.
  • The custom/manual package-selection flow intentionally retains all choices so the user can select a source explicitly.
  • Deterministic output can change the relative order of pyproject.toml and requirements arguments compared with the previous asynchronous implementation. This is worth reviewing because uv uses user input order as one resolver-priority tie-breaker.
  • Path containment is lexical. Symlinked or differently aliased paths are not resolved through the filesystem.

Validation

  • npm run compile-tests
  • npm run lint
  • Focused getProjectInstallable suites: 16 passing
  • Full unit suite: 1,279 passing, 2 pending

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 8f42031a-bd90-4448-bffe-b5c0ab522b6d
@StellaHuang95 StellaHuang95 added the bug Issue identified by VS Code Team member as probable bug label Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Issue identified by VS Code Team member as probable bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Duplicate install automatically attempted in folder with git worktrees

1 participant