mirror of
https://github.com/pnpm/pnpm.git
synced 2026-06-28 09:55:39 -04:00
When a package is reused from the lockfile, its child edges are taken verbatim and bypass the preferred-versions walk, so a transitive dependency can stay pinned to an older version even after a direct dependency resolved to a higher version that satisfies the same range — leaving the lockfile non-convergent (an incremental install keeps a duplicate that a fresh install would not). The resolver now refreshes such a stale pin to the higher direct-dependency version during resolution, via `preferredVersion` (singular), which overrides the EXISTING_VERSION_SELECTOR_WEIGHT stability bias. The older version is never resolved or fetched, and the incremental result converges to what a fresh install produces. The pick is anchored to direct dependencies (which resolve first), so it restores the automatic dedupe removed in pnpm/pnpm#11110 without reintroducing its non-determinism, and unlike the post-pass in pnpm/pnpm#11502 it does not over-fetch. pacquet is ported in the same change. Its full-subtree lockfile reuse is coarser than pnpm's per-edge reuse, so it records per importer which direct deps changed and their resolved versions, declines full-subtree reuse for a parent that depends on a changed direct dep, and forces the higher version in the child walk. Range satisfaction uses plain semver (not prerelease-inclusive), matching pnpm's semver.satisfies(.., true).