Hello, I have found a bug in "cp -rfs". Steps to reproduce: 1. Given "path1" and "path2" are on different devices. 2. $ touch "path1/file" 3. $ cd path2/; ln -s path1/file 4. $ cp --symbolic-link --force --recursive path1/file . Expected: The link is overwritten with an exact copy. Actual result: cp shows an error: cp: 'path1/file' and './file' are the same file This bug was introduced in http://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=376967889ed7ed561e46ff6d88a66779db62737a Specifically this hunk: diff --git a/src/copy.c b/src/copy.c index e3832c2..9dbd536 100644 --- a/src/copy.c +++ b/src/copy.c @@ -46,6 +46,7 @@ #include "file-set.h" #include "filemode.h" #include "filenamecat.h" +#include "force-link.h" #include "full-write.h" #include "hash.h" #include "hash-triple.h" @@ -1623,11 +1624,13 @@ same_file_ok (char const *src_name, struct stat const *src_sb, } } - /* It's ok to remove a destination symlink. But that works only when we - unlink before opening the destination and when the source and destination - files are on the same partition. */ - if (x->unlink_dest_before_opening - && S_ISLNK (dst_sb_link->st_mode)) + /* It's ok to remove a destination symlink. But that works only + when creating symbolic links, or when the source and destination + are on the same file system and when creating hard links or when + unlinking before opening the destination. */ + if (x->symbolic_link + || ((x->hard_link || x->unlink_dest_before_opening) + && S_ISLNK (dst_sb_link->st_mode))) return dst_sb_link->st_dev == src_sb_link->st_dev; if (x->dereference == DEREF_NEVER) Two patches that fix the issue are attached. They are against the current master in https://github.com/coreutils/coreutils The changes are also here: https://github.com/coreutils/coreutils/compare/master...ilya-bobyr:master Thank you, Illia Bobyr