[PATCH v3 0/2] MR11529: cmd: Skip MOVE when source and destination are the same file
When 'move file' is called without a destination, the destination defaults to the current directory, causing source and destination paths to resolve to the same file. This led to an overwrite prompt or, in batch mode, a failed MoveFileExW call. Compare the fully-resolved source and destination case-insensitively and skip the move operation when they are identical. Fixes bug \[#28582\](https://bugs.winehq.org/show_bug.cgi?id=28582) Pls tell me if anything else needs to be added or I need to add/remove any other test case Signed-off-by: Lokesh Poovaragan lokesh.poovaragan@gmail.com -- v3: cmd: Skip MOVE when source and destination are the same file cmd/tests: Add tests for MOVE to current directory https://gitlab.winehq.org/wine/wine/-/merge_requests/11529
From: Lokesh Poovaragan <lokesh.poovaragan@gmail.com> Add test cases for moving files to the current directory (no-op when source already resides there): - move file to itself explicitly - move file without destination argument - move .\file without destination (explicit prefix) Signed-off-by: Lokesh Poovaragan <lokesh.poovaragan@gmail.com> --- programs/cmd/tests/test_builtins.bat | 6 ++++++ programs/cmd/tests/test_builtins.bat.exp | 6 ++++++ programs/cmd/tests/test_builtins.cmd | 6 ++++++ programs/cmd/tests/test_builtins.cmd.exp | 6 ++++++ 4 files changed, 24 insertions(+) diff --git a/programs/cmd/tests/test_builtins.bat b/programs/cmd/tests/test_builtins.bat index 7711aa917e3..cfaf50ac4e7 100644 --- a/programs/cmd/tests/test_builtins.bat +++ b/programs/cmd/tests/test_builtins.bat @@ -138,6 +138,12 @@ mkdir foo & cd foo echo a > fileA echo b > fileB call :setError 666 & (move >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (move fileA fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +if exist fileA echo ok +call :setError 666 & (move fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +if exist fileA echo ok +call :setError 666 & (move .\fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +if exist fileA echo ok call :setError 666 & (move fileA fileC >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (move fileC nowhere\fileC >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (move fileD fileE >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) diff --git a/programs/cmd/tests/test_builtins.bat.exp b/programs/cmd/tests/test_builtins.bat.exp index 77ca71c8778..d4c400fc65e 100644 --- a/programs/cmd/tests/test_builtins.bat.exp +++ b/programs/cmd/tests/test_builtins.bat.exp @@ -93,6 +93,12 @@ SUCCESS 0 a@space@ --- success/failure for MOVE command FAILURE 1 +@todo_wine@SUCCESS 0 +ok +@todo_wine@SUCCESS 0 +ok +@todo_wine@SUCCESS 0 +ok SUCCESS 0 FAILURE 1 FAILURE 1 diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd index 34d1f076485..6166edfe18c 100644 --- a/programs/cmd/tests/test_builtins.cmd +++ b/programs/cmd/tests/test_builtins.cmd @@ -721,6 +721,12 @@ mkdir foo & cd foo echo a > fileA echo b > fileB call :setError 666 & (move >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +call :setError 666 & (move fileA fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +if exist fileA echo ok +call :setError 666 & (move fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +if exist fileA echo ok +call :setError 666 & (move .\fileA >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) +if exist fileA echo ok call :setError 666 & (move fileA fileC >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (move fileC nowhere\fileC >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) call :setError 666 & (move fileD fileE >NUL &&echo SUCCESS !errorlevel!||echo FAILURE !errorlevel!) diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index dc6420e1432..911ef0791b1 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -612,6 +612,12 @@ SUCCESS 0 a@space@ --- success/failure for MOVE command FAILURE 1 +@todo_wine@SUCCESS 0 +ok +@todo_wine@SUCCESS 0 +ok +@todo_wine@SUCCESS 0 +ok SUCCESS 0 FAILURE 1 FAILURE 1 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11529
From: Lokesh Poovaragan <lokesh.poovaragan@gmail.com> When 'move file' is called without a destination, the destination defaults to the current directory, causing source and destination paths to resolve to the same file. This led to an overwrite prompt or, in batch mode, a failed MoveFileExW call. Compare the fully-resolved source and destination case-insensitively and skip the move operation when they are identical. Signed-off-by: Lokesh Poovaragan <lokesh.poovaragan@gmail.com> --- programs/cmd/builtins.c | 4 ++++ programs/cmd/tests/test_builtins.bat.exp | 6 +++--- programs/cmd/tests/test_builtins.cmd.exp | 10 +++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index b706feb39c7..9f98b205065 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1910,6 +1910,10 @@ RETURN_CODE WCMD_move(void) WINE_TRACE("Source '%s'\n", wine_dbgstr_w(src)); WINE_TRACE("Dest '%s'\n", wine_dbgstr_w(dest)); + /* If source and destination are the same file, skip (no-op) */ + if (!lstrcmpiW(src, dest)) + continue; + /* If destination exists, prompt unless /Y supplied */ if (GetFileAttributesW(dest) != INVALID_FILE_ATTRIBUTES) { BOOL force = FALSE; diff --git a/programs/cmd/tests/test_builtins.bat.exp b/programs/cmd/tests/test_builtins.bat.exp index d4c400fc65e..f900a5813ba 100644 --- a/programs/cmd/tests/test_builtins.bat.exp +++ b/programs/cmd/tests/test_builtins.bat.exp @@ -93,11 +93,11 @@ SUCCESS 0 a@space@ --- success/failure for MOVE command FAILURE 1 -@todo_wine@SUCCESS 0 +SUCCESS 0 ok -@todo_wine@SUCCESS 0 +SUCCESS 0 ok -@todo_wine@SUCCESS 0 +SUCCESS 0 ok SUCCESS 0 FAILURE 1 diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp index 911ef0791b1..daa79804126 100644 --- a/programs/cmd/tests/test_builtins.cmd.exp +++ b/programs/cmd/tests/test_builtins.cmd.exp @@ -612,11 +612,11 @@ SUCCESS 0 a@space@ --- success/failure for MOVE command FAILURE 1 -@todo_wine@SUCCESS 0 +SUCCESS 0 ok -@todo_wine@SUCCESS 0 +SUCCESS 0 ok -@todo_wine@SUCCESS 0 +SUCCESS 0 ok SUCCESS 0 FAILURE 1 @@ -1826,8 +1826,8 @@ file move with overwrite succeeded@or_broken@file overwrite impossible! bar@or_broken@baz read-only files are moveable file moved in subdirectory -moving a file to itself is a no-op@or_broken@moving a file to itself should be a no-op! -ErrorLevel: 0@or_broken@ErrorLevel: 1 +moving a file to itself is a no-op +ErrorLevel: 0 --- directory move simple directory move succeeded moving a directory to itself gives error; errlevel 1 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11529
On Fri Jul 31 07:52:21 2026 +0000, eric pouech wrote:
I guess you want `@todo_wine@SUCCESS 0` switching to use todo_wine instead of or_broken from now, testing it locally, will add additional commits until it turns green on all platforms in the CI
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/11529#note_147445
closing as confliction with Wine patch policy -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11529#note_148396
This merge request was closed by eric pouech. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11529
participants (3)
-
eric pouech (@epo) -
Lokesh Poovaragan -
Lokesh Poovaragan (@lokeshpoovaragan)