fix: muse status no longer misclassifies directories with only ignored files as untracked (muse#76)
Root cause confirmed exactly as scoped in the ticket: CodePlugin.stage_status()'s os.walk loop pruned a directory from the walk only when the DIRECTORY NAME ITSELF matched an ignore pattern. A file-level pattern (e.g. "onlyignored/lockfile.txt") doesn't prune the directory -- os.walk still descends into it, adds it to on_disk_dirs, then correctly excludes the one ignored file from workdir_files. dirs_with_workdir_files is derived only from workdir_files, so the directory never lands in it. empty_on_disk_dirs (on_disk_dirs - dirs_with_workdir_files) then classified the directory as an "empty on-disk directory" -- even though its only content is legitimately ignored, not actually empty -- and it flowed into dir_added, rendered by `muse status` as "untracked directory: ...".
Fix (Phase 2, exactly as scoped): track a new set, dirs_with_any_file, populated for EVERY regular file encountered during the walk (all ancestor path components, matching dirs_with_workdir_files's own prefix-walk semantics) -- BEFORE the is_ignored check, so it includes directories whose only content is ignored. empty_on_disk_dirs now subtracts both dirs_with_workdir_files AND dirs_with_any_file, so a directory with only ignored content is excluded from the empty-dir candidate set entirely. No change to the directory-NAME-level ignore pruning (dirnames[:] = ...) -- that mechanism was already correct and unrelated to this bug, per the ticket's explicit scope.
New regression tests in tests/test_status_directory_tracking.py (TestDirectoryWithOnlyIgnoredContent), matching the ticket's Phase 1 spec exactly: - STATUSDIR_01: directory with only an individually-ignored file must not appear in `untracked`. Confirmed genuine RED against current code before the fix. - STATUSDIR_02: `muse status` and `muse diff` must agree -- committed the ignore-pattern change first so it isn't itself a pending change, isolating the exact cross-command disagreement the ticket reported (diff.has_changes == false, status still flagged the directory). Confirmed genuine RED. - STATUSDIR_03: a genuinely empty directory (no ignore involved) must still be reported as untracked/addable -- regression guard for the pre-existing empty-dir-tracking feature. Already passed pre-fix, as expected (this is a guard, not a repro). - STATUSDIR_04: a directory with one ignored file and one real file must surface in untracked only via the real file's own path, and `muse code add` on the directory must stage only the real file, never a directory sentinel. Already passed pre-fix, as expected.
Live-reproduced the ticket's exact repro (mkdir onlyignored + TOML .museignore pattern) via muse-dev in a disposable /tmp sandbox before and after: `onlyignored/` disappeared from `untracked` after the fix, while a sibling genuinely-empty directory and a mixed ignored+real-file directory both continued to behave correctly.
Targeted regression suite (Phase 3, exactly as scoped) -- test_status_directory_tracking.py (14, including the 4 new tests), test_directory_tracking.py, test_dir_lifecycle.py, test_directories_feature.py, test_cmd_status.py, test_cmd_code_add.py -- all pass (285 passed), zero regressions.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Semantic Changes
7 symbols
Files Changed
~2
1216 in snapshot
0 comments
muse hub commit comment sha256:8ab72466cbde2db46324e13860aec931ec612c075bd0ef9e0f2245914089664b --body "your comment"
No comments yet. Be the first to start the discussion.