Migrating from CPM
Convert an existing solution (with or without CPM) into a PCPM workspace in one command.
If you already have a .NET solution with or without Central Package
Management, pcpm convert migrates it in place.
What it does
pcpm convert walks your workspace, looks at every <PackageReference />
in every .csproj, and:
- Adopts your existing
Directory.Packages.propsif you have one, and rewrites every<PackageReference Include="X" Version="1.2.3" />to<PackageReference Include="X" />(no version, since the version now lives in CPM). - Creates
Directory.Packages.propsif you don’t have one, and hoists every per-project version into a<PackageVersion />entry. - Writes
pcpm.jsonand, in monorepo mode,pcpm-workspace.yaml. - Runs
pcpm installto materialise the store and produce the initialpcpm.lock.
The whole thing is a no-op if the workspace is already in PCPM’s expected shape.
Running it
pcpm convert
In a monorepo:
pcpm convert --workspace
The --workspace flag tells PCPM to write a pcpm-workspace.yaml that
covers all discovered projects. Without it, PCPM only looks at the
.sln in the current directory (or one level up).
What it does NOT do
pcpm convert is conservative by design. It does not:
- Touch your
.csprojfiles beyond the version-stripping described above. Project structure, SDKs, and properties are all left alone. - Change your NuGet feed configuration. Existing
NuGet.configfiles are kept as-is; PCPM reads them and writes the same feeds intopcpm.jsonfor its own use. - Update packages.
pcpm convertonly normalises your existing versions into CPM. To bump versions, runpcpm update <pkg>after the convert.
Example
Starting state:
<!-- src/Api/Api.csproj -->
<ItemGroup>
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup>
After pcpm convert:
<!-- Directory.Packages.props (created) -->
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Serilog" Version="3.1.1" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup>
</Project>
<!-- src/Api/Api.csproj (modified) -->
<ItemGroup>
<PackageReference Include="Serilog" />
<PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>
And the new files:
pcpm.jsonpcpm.lock(afterpcpm install)
Rolling back
pcpm convert is not destructive — it only edits files under the
workspace root, and those edits are diff-friendly. To roll back:
git restore .
That reverts every file PCPM touched, including the new manifests.
pcpm.lock and pcpm.json will disappear from the diff.
Tips for a smooth conversion
- Do it in a branch. Always. The diff is small but the implications for the rest of your team are not.
- Run
dotnet buildafter the convert. If anything is wrong, it’ll show up as a missing<PackageVersion />or a project that wasn’t picked up by the discovery. - Don’t combine the convert with version bumps. First get the
shape right, then
pcpm updatedeliberately.