Skip to content

Fix/tfm floor and mirrored file tracking - #36

Merged
kieronlanning merged 3 commits into
mainfrom
fix/tfm-floor-and-mirrored-file-tracking
Oct 8, 2026
Merged

kieronlanning merged 3 commits into
mainfrom
fix/tfm-floor-and-mirrored-file-tracking

Conversation

@kieronlanning

Copy link
Copy Markdown
Contributor

No description provided.

A project declaring TargetFrameworks in its body opts out of the curated set
resolution, but the last-resort floor further down Sdk.props still fired: the
body has not been evaluated at that point, so both TFM properties still read
empty. The project then carried TargetFramework set to the Current set
alongside its own list, and MSBuild honours the singular property - so it
quietly built a single target and every multi-targeting consumer failed with
"Project 'X' targets 'net10.0'. It cannot be referenced by a project that
targets '.NETCoreApp,Version=v9.0'".

The floor now stands down for the same declaration the set resolution stands
down for.

A project's own PurviewTargetFrameworkSet also wins over one the repository
selected. The selection is read out of the project XML precisely so a project
can make it, but it was then applied only when nothing had been inherited, so
a repository-wide choice silently overrode it - the opposite of the documented
narrowest-first layering.
Git applies ignore rules only to untracked paths, so a mirrored file that is
tracked - usually committed before the SDK began ignoring mirrored files per
file - is never ignored. Every upgrade that changes it rewrites it and it shows
up as a local modification, which reads as the SDK dirtying the working tree.
The repository has to untrack it once and the SDK cannot do that for it, so it
now reports PurviewTrackedMirroredFile naming the paths and the
`git rm --cached` command. DisableMirroredFileTrackingCheck=true opts out.

The check only runs on a build that actually mirrored something - both the
moment the churn appears and the moment the advice applies - so an up-to-date
build spawns no git process.

Also guards the agent-sync manifest read-merge-write with a cross-process named
mutex. Every project and both mirror targets rewrite the whole manifest from
their own change groups plus whatever they read of the others, so unsynchronised
writers drop each other's groups and the generated .gitignore under-covers. This
narrows that window; it does not close it entirely.

The harness gains RunGitAsync and clears read-only attributes before deleting a
work directory, which a `git init` leaves behind.
@kieronlanning
kieronlanning merged commit 834214e into main Oct 8, 2026
4 checks passed
@kieronlanning
kieronlanning deleted the fix/tfm-floor-and-mirrored-file-tracking branch October 8, 2026 17:45
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.

1 participant