Skip to content

fix(batch-rename): recognize case-only self-rename on case-insensitive FS - #8

Merged
lukisch merged 1 commit into
masterfrom
fix/T-20260926-samefile-only
Sep 26, 2026
Merged

lukisch merged 1 commit into
masterfrom
fix/T-20260926-samefile-only

Conversation

@lukisch

@lukisch lukisch commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator

Aufgeteilt aus PR #6 (Team-Lead-Entscheid): merge-reviewer hat gemessen, dass PR#6 unter Windows stabil schlechter war als master (0/9 vs. 6/9 gruen, p≈0,01), zurueckgefuehrt auf den inzwischen revertierten conftest.py-Versuch. Dieser PR enthaelt NUR den unabhaengigen os.path.samefile()-Fix fuer Case-only-Renames auf case-insensitiven Dateisystemen (behebt 2 echte Testfehler auf macOS). 3x CI-Wiederholung folgt, Belege gehen in Ticket T-20260926-987151525.

…e FS

Split out of PR #6 at team-lead's request (measured Windows regression
there was traced to the conftest.py Qt-teardown attempt, reverted; this
fix is unrelated and independently verified).

test_case_only_rename_is_actionable_not_unchanged and
test_batch_rename_dialog_case_mode_and_execution failed on macOS
(AssertionError: Status sollte 'ok' sein, war aber 'collision'), passing
on Linux and Windows.

Root cause: generate_preview()'s "is this a case-only self-rename" check
compared os.path.normcase(new_path) == os.path.normcase(original_path).
os.path.normcase() reflects the OS's PATH-STRING convention (lowercases
on Windows, no-op on POSIX) -- it says nothing about the actual
filesystem's case sensitivity. macOS is the classic mismatch: its path
convention is POSIX/case-sensitive (normcase is a no-op there), but its
default filesystem (APFS) is case-INsensitive, so "sample.txt" and
"SAMPLE.txt" are the same file on disk despite differing normcase
strings. The self-rename bypass therefore never triggered, and the
subsequent os.path.exists(item.new_path) check found the (same) file
already "there" and flagged it as an external collision.

Fix: after the normcase check, also compare via os.path.samefile() when
both paths exist -- this checks actual inode/device identity and
correctly recognizes the case-only self-rename on any case-insensitive
filesystem regardless of the OS's path-string convention. Guarded
against a not-yet-existing target with a double os.path.exists() check
before the call plus try/except OSError as a safety net.
@github-actions

Copy link
Copy Markdown

Welcome! Thanks for your first pull request in this repository.

A maintainer will review it soon. Please make sure:

  • Your changes are tested
  • Documentation is updated if needed
  • The PR description explains what changed and why

Thanks for contributing.

@lukisch

lukisch commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator Author

Freigegeben zur Review durch Team-Lead: 5/9 Windows-Legs bei 3x Wiederholung, im Rahmen der master-Referenz (6/9). Enthaelt nur den samefile()-Fix fuer Case-only-Renames (echter Produktfix, behebt 2 macOS-Testfehler). @merge-reviewer bitte pruefen.

@lukisch

lukisch commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator Author

Review (merge-reviewer, claude-opus) auf Head 3cd7f0a: OK. samefile greift nur, wenn der normcase-Vergleich nicht gleich ist und beide Pfade existieren, OSError wird abgefangen. Unter Linux (case-sensitiv) bleibt eine echte Kollision eine Kollision. In der CI bestehen die beiden macOS-case-only-Tests jetzt. Übrig bleibt nur der startfile-Test, den #7 behebt, plus der bekannte Teardown-Crash. Windows 5/9 gegen master 6/9 ist kein belegter Unterschied, und dort greift normcase vor samefile. Randfall, nicht blockierend: Zwei Hardlinks derselben Datei gelten als „dieselbe Datei“ und werden nicht als Kollision gemeldet. Admin-Merge über team-lead.

@lukisch
lukisch merged commit d22f5fe into master Sep 26, 2026
9 of 31 checks passed
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