Windows: brename doesn't detect when files will be overwritten if the replacement only differs in case
tspivey opened this issue · 9 comments
Using brename v2.12.0 on Windows.
Create two files, test.txt and test.doc.
brename -x -p "\..+$" -r "" -d
[INFO] checking: [ ok ] 'test.doc' -> 'test'
[ERRO] checking: [ overwriting newly renamed path ] 'test.txt' -> 'test'
[ERRO] 1 potential error(s) detected, please check
This works as expected. Now create test.txt and Test.doc.
brename -x -p "\..+$" -r "" -d
[INFO] checking: [ ok ] 'Test.doc' -> 'Test'
[INFO] checking: [ ok ] 'test.txt' -> 'test'
[INFO] 2 path(s) to be renamed
Now do the rename:
brename -x -p "\..+$" -r ""
[INFO] renamed: 'Test.doc' -> 'Test'
[INFO] renamed: 'test.txt' -> 'test'
[INFO] 2 path(s) renamed
Only one file remains in the directory, because NTFS is case insensitive.
Thanks for reporting, and I've added a flag -w/--case-insensitive-path
for correctly checking file overwrites in file systems like NTFS (mostly in Windows).
Right now, we show the warning message if it's not set in all operating systems. Should I make it on default for the Windows version?
$ brename -x -p "\..+$" -r "" -i -f ^Test -d
[INFO] main options:
[INFO] ignore case: true
[INFO] search pattern: (?i)\..+$
[INFO] skip filters: ^\.
[INFO] include filters: ^Test
[WARN]
[WARN] If the file system where the search path locates is NTFS (mostly in Windows),
[WARN] please use -w/--case-insensitive-path to correctly check file overwrites!
[WARN]
[INFO] search paths: ./
[INFO]
[INFO] checking: [ ok ] 'Test.doc' -> 'Test'
[INFO] checking: [ ok ] 'test.txt' -> 'test'
[INFO] 2 path(s) to be renamed
Hmm, I think it should be set by default on Windows.
On Linux, we also show the warning message in case users are operating on an external disk with NTFS.
brename -x -p "\..+$" -r "" -i -f ^Test -d
[WARN]
[WARN] If the file system where the search path locates is NTFS (mostly on Windows),
[WARN] please use -w/--case-insensitive-path to correctly check file overwrites!
[WARN]
[INFO] main options:
[INFO] path filters and search pattern:
[INFO] ignore case: true
[INFO] search pattern: (?i)\..+$
[INFO] replacement:
[INFO]
[INFO] skip filters: ^\.
[INFO] include filters: ^Test
[INFO]
[INFO] path overwrite checking:
[INFO] case-insensitive path: false
[INFO] overwrite mode: 0 (reporting error)
[INFO]
[INFO] ------------------------------------------------------
[INFO]
[INFO] search paths: ./
[INFO]
[INFO] checking: [ ok ] 'Test.doc' -> 'Test'
[INFO] checking: [ ok ] 'test.txt' -> 'test'
[INFO] 2 path(s) to be renamed
Thanks for fixing this. Some edge cases:
- It's possible to make a folder case sensitive on Windows (
fsutil file setCaseSensitiveInfo pathname
). I don't know where this is used. - Renaming a file strictly by case should probably be considered not an error (e.g. test.TXT to test.txt).
For case 1, I also noticed the setting somewhere too. As you said, it's an edge case. For most cases, we would better assume Windows users use case-intensive file systems. Then, for these professional users who can run tools like fsutil
, we can offer another flag to disable the flag of -w/--case-insensitive-path
, like -W/--case-sensitive-path
.
For case 2, renaming test.TXT
to test.txt
should be stopped in case-sensitive filesystems when text.txt
exists.
[ERRO] checking: [ new path existed ] 'test.TXT' -> 'test.txt'
Updates: You're right. In my test, it reported the new path existed
error even when only one file exists. I'm testing this in a virtual Windows machine where the disk is partitioned as EXT4! The file path package in Golang thinks the file exists already.
I've added the -W/--case-sensitive-path
and the case 2 is fixed.
Warnings:
1. The path in file systems like NTFS is case-insensitive, so you should switch on the flag
-w/--case-insensitive-path to correctly check file overwrites.
2. The flag -w/--case-insensitive-path is switched on by default on Windows, please use
-W/--case-sensitive-path to disable it if the file system is indeed case sensitive.
Flags:
-w, --case-insensitive-path the file system (e.g., NTFS) is case-insensitive. It's automatically
swiched on on Windows
-W, --case-sensitive-path believing that the file system is case-sensitive. Please use this to
disable the flag -w/--case-insensitive-path, which is switched on by
default on Windows
Here are some tests on Windows with two files (test.TXT
and Test.doc
) in one directory. The file system is ext2/ext3 according to the information from stat -f
; actually, it's ext4.
test 1
Since it's ext4, I believe the paths should be case-sensitive, so I add -W
.
test 2
Please help to test it. (commit 8b708c6)
@tspivey I'll tag a new release if it works as expected :)
I verified:
- with test.txt and Test.doc, removing the extension fails because the files would conflict in case.
- I could rename test.TXT to test.txt without problems.
I'm trying to come up with some edge cases reading the official documentation.
Do not end a file or directory name with a space or a period. Although the underlying file system may support such names, the Windows shell and user interface does not. However, it is acceptable to specify a period as the first character of a name. For example, ".temp".
This might be a separate issue since it doesn't have anything to do with case, but it can also cause data loss on NTFS. if I create test.txt
and test..txt
, then do:
brename -p ".txt$" -r ""
I'm left with test
, and one of the files is lost.
with test.txt and Test.doc, removing the extension fails because the files would conflict in case.
OK, it's exptected.
I could rename test.TXT to test.txt without problems.
Cool.
Do not end a file or directory name with a space or a period. Although the underlying file system may support such names, the Windows shell and user interface does not.
🤮 Have to add another rule ...
Do not end a file or directory name with a space or a period. Although the underlying file system may support such names, the Windows shell and user interface does not.
OK, they are not allowed now.
$ brename -p '.txt' -d
[ERRO] checking: [ new path ending with a period ] 'test..txt' -> 'test.'
[INFO] checking: [ ok ] 'test.txt' -> 'test'
[ERRO] 1 potential error(s) detected, please check
A warning message is added in the help message.
Warnings:
1. The path in file systems like FAT32 or NTFS is case-insensitive, so you should switch on the flag
-w/--case-insensitive-path to correctly check file overwrites.
2. The flag -w/--case-insensitive-path is switched on by default on Windows, please use
-W/--case-sensitive-path to disable it if the file system is indeed case-sensitive.
3. New paths ending with a period of space, being error-prone, are not allowed.