]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
mv: better diagnostic for 'mv dir x' failure
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 22 Jul 2023 20:39:17 +0000 (13:39 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 22 Jul 2023 20:41:07 +0000 (13:41 -0700)
Problem reported by Nir Oren <https://bugs.gnu.org/64785>.
* src/copy.c (copy_internal): Use a more-specific diagnostic when
a rename fails due to a problem that must be due to the
destination, avoiding user confusion in cases like 'mv dir x'
where x is a nonempty directory.
* tests/mv/dir2dir.sh: Adjust to match.

NEWS
src/copy.c
tests/mv/dir2dir.sh

diff --git a/NEWS b/NEWS
index 7d2ca7f6b575dc0d8b8cf25e8312f7d8fba13cd1..bd0c59eb5f87fa541b233861981e79015042b4b7 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -56,6 +56,13 @@ GNU coreutils NEWS                                    -*- outline -*-
   short option is reserved to better support emulation of the standalone
   checksum utilities with cksum.
 
+  'mv dir x' now complains differently if x/dir is a nonempty directory.
+  Previously it said "mv: cannot move 'dir' to 'x/dir': Directory not empty",
+  where it was unclear whether 'dir' or 'x/dir' was the problem.
+  Now it says "mv: cannot overwrite 'x/dir': Directory not empty".
+  Similarly for other renames where the destination must be the problem.
+  [problem introduced in coreutils-6.0]
+
 ** Improvements
 
   cp, mv, and install now avoid copy_file_range on linux kernels before 5.3
index ddc9eab302c4aca8b5e3d5d85d8d22c07c17f044..90eebf6bc35c59688191b5ba4b409a9dc0730913 100644 (file)
@@ -2840,9 +2840,23 @@ skip:
              If the permissions on the directory containing the source or
              destination file are made too restrictive, the rename will
              fail.  Etc.  */
-          error (0, rename_errno,
-                 _("cannot move %s to %s"),
-                 quoteaf_n (0, src_name), quoteaf_n (1, dst_name));
+          char const *quoted_dst_name = quoteaf_n (1, dst_name);
+          switch (rename_errno)
+            {
+            case EDQUOT: case EEXIST: case EISDIR: case EMLINK:
+            case ENOSPC: case ENOTEMPTY: case ETXTBSY:
+              /* The destination must be the problem.  Don't mention
+                 the source as that is more likely to confuse the user
+                 than be helpful.  */
+              error (0, rename_errno, _("cannot overwrite %s"),
+                     quoted_dst_name);
+              break;
+
+            default:
+              error (0, rename_errno, _("cannot move %s to %s"),
+                     quoteaf_n (0, src_name), quoted_dst_name);
+              break;
+            }
           forget_created (src_sb.st_ino, src_sb.st_dev);
           return false;
         }
index ea99eca56510b5f2620ae920cd65f44768024551..da6a518e58ba8a702e790ef5f8f0719c2fab4f68 100755 (executable)
@@ -34,7 +34,7 @@ sed             's/: File exists/: Directory not empty/'<out>o1;mv o1 out
 sed 's/: Device or resource busy/: Directory not empty/'<out>o1;mv o1 out
 
 cat <<\EOF > exp || framework_failure_
-mv: cannot move 'b/t' to 'a/t': Directory not empty
+mv: cannot overwrite 'a/t': Directory not empty
 EOF
 
 compare exp out || fail=1