summaryrefslogtreecommitdiff
path: root/src/copy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/copy.c')
-rw-r--r--src/copy.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/src/copy.c b/src/copy.c
index 51c5f6db8..66ffbf85d 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -39,6 +39,7 @@
#include "quote.h"
#include "same.h"
#include "savedir.h"
+#include "utimecmp.h"
#include "utimens.h"
#include "xreadlink.h"
@@ -945,16 +946,28 @@ copy_internal (const char *src_path, const char *dst_path,
return 1;
}
- if (x->update && MTIME_CMP (src_sb, dst_sb) <= 0)
+ if (x->update)
{
- /* We're using --update and the source file is older
- than the destination file, so there is no need to
- copy or move. */
- /* Pretend the rename succeeded, so the caller (mv)
- doesn't end up removing the source file. */
- if (rename_succeeded)
- *rename_succeeded = 1;
- return 0;
+ /* When preserving time stamps (but not moving within a file
+ system), don't worry if the destination time stamp is
+ less than the source merely because of time stamp
+ truncation. */
+ int options = ((x->preserve_timestamps
+ && ! (x->move_mode
+ && dst_sb.st_dev == src_sb.st_dev))
+ ? UTIMECMP_TRUNCATE_SOURCE
+ : 0);
+
+ if (0 <= utimecmp (dst_path, &dst_sb, &src_sb, options))
+ {
+ /* We're using --update and the destination is not older
+ than the source, so do not copy or move. Pretend the
+ rename succeeded, so the caller (if it's mv) doesn't
+ end up removing the source file. */
+ if (rename_succeeded)
+ *rename_succeeded = 1;
+ return 0;
+ }
}
}