Clean by deleting bin and obj, not by asking dotnet to - #43
Merged
Conversation
`dotnet clean` removes what the configuration and target framework you name would have produced. Everything else it leaves, and there was a great deal of it: 485 MB of `net10.0-windows` output stranded when the app retargeted to Windows 11 a fortnight ago, and 183 MB of `obj\scratch*` trees from builds that had redirected their output path to get around a locked DLL. Two thirds of a gigabyte that no build would ever look at again, surviving every clean anyone ran. None of it appeared in `git status`, which is why it lasted. `[Oo]bj/` and `[Bb]in/` are unanchored, so they match at any depth and the residue was ignored from the moment it was written. That is the right rule - the variant it does not cover, an output directory at the project root, shows up as untracked and gets noticed the same day - but it does mean nothing was ever going to point at this. So `-Clean` deletes both folders beside every project in the solution and says what it freed. It ignores `-Configuration` deliberately: the whole value is in taking the configurations you are not building, since those are the ones nothing else will touch. It walks the `.csproj` files rather than sweeping the tree recursively, so it cannot wander into `.git`, `.vs`, or a vendored folder that happens to contain a `bin`. Failing to delete a folder now names the likely cause. A running Offstream holds its own binaries open, and Windows reports that as a file it cannot access - true, unhelpful, and the same message you get for half a dozen unrelated problems. Worth spending a line on, because this is also where the `obj\scratch*` trees came from: redirecting the output path gets past the lock, and quietly leaves the copy behind. The plan gets the finding beside the one about `build.ps1` holding a second copy of the TFM, since they are the same lesson from opposite ends - changing the TFM invalidates paths that no longer appear anywhere in the build, and the ones already on disk have nothing left that knows their name. The README's test count said 1,089 and the suite is 1,128. Corrected while in the file rather than left to drift further. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
dotnet cleanremoves what the configuration and target framework you name would have produced. Everything else it leaves, and there was a great deal of it — 645 MB, found while clearing the working tree:dotnet cleannever reached itnet10.0-windows/output (24 dirs)obj/{s,scratch,scratch2,scratchbuild}/(9 dirs)BaseOutputPathto get past a locked DLL.spike/obj/shell outlived it.*_wpftmp.csproj.nuget.*None of it appeared in
git status, which is why it lasted.[Bb]in/and[Oo]bj/are unanchored, so they match at any depth and the residue was ignored from the moment it was written. That is the right rule — the variant it doesn't cover, an output directory at the project root, shows up as untracked and gets noticed the same day — but it does mean nothing was ever going to point at this.What changed
-Cleannow deletesbin/andobj/beside every project in the solution and reports what it freed:-Configuration. The whole value is in taking the configurations you are not building — those are the ones nothing else will touch..csprojfiles rather than sweeping the tree recursively, so it cannot wander into.git,.vs, or a vendored folder that happens to contain abin.obj/scratch*trees came from: redirecting the output path gets past the lock and quietly leaves the copy behind.Verification
bin/Release/net10.0-windows/and anobj/scratch9/, the two classesdotnet cleanstructurally cannot reach. Both removed, 0 survivors.Offstream.Core.dllfrom a separate process and confirmed the guidance fires rather than the raw Windows message.build.ps1 -Clean -Testfrom an empty tree — Build succeeded, 0 warnings, 0 errors; 924 Core + 204 UI passing, 0 failures.build.ps1 -VerifyFormat— exit 0.Docs
CHANGELOG.mdunder[Unreleased]. The README's-Cleanhelp line, plus its test count, which said 1,089 against a suite of 1,128 — corrected while in the file rather than left to drift further. The plan gets the finding beside the one aboutbuild.ps1holding a second copy of the TFM, since they are the same lesson from opposite ends: changing the TFM invalidates paths that no longer appear anywhere in the build, and the ones already on disk have nothing left that knows their name.🤖 Generated with Claude Code