mirror of
https://github.com/rclone/rclone.git
synced 2026-05-14 19:34:25 -04:00
sync: fix --fix-case rename on backends that need upload before overwrite
operations.NeedTransfer's equality check may have deleted pair.Dst as a precursor to re-uploading it if SetModTime returns ErrorCantSetModTimeWithoutDelete (e.g. Dropbox). If so skip the eager delete of the destination if --fix-case will rename it to a different name. The rename itself replaces the destination, and any subsequent re-upload happens at the correctly-cased path. See: #8881
This commit is contained in:
@@ -392,13 +392,26 @@ func (s *syncCopyMove) pairChecker(in *pipe, out *pipe, fraction int, wg *sync.W
|
||||
}
|
||||
}
|
||||
// Fix case for case insensitive filesystems
|
||||
if s.ci.FixCase && !s.ci.Immutable && src.Remote() != pair.Dst.Remote() {
|
||||
if newDst, err := operations.Move(s.ctx, s.fdst, nil, src.Remote(), pair.Dst); err != nil {
|
||||
fs.Errorf(pair.Dst, "Error while attempting to rename to %s: %v", src.Remote(), err)
|
||||
s.processError(err)
|
||||
} else {
|
||||
fs.Infof(pair.Dst, "Fixed case by renaming to: %s", src.Remote())
|
||||
pair.Dst = newDst
|
||||
if s.ci.FixCase && !s.ci.Immutable && pair.Dst != nil && src.Remote() != pair.Dst.Remote() {
|
||||
// NeedTransfer's equality check may have deleted pair.Dst as a precursor
|
||||
// to re-uploading it (the way modtime updates are done on backends like
|
||||
// Dropbox that can't set modtime in place). If so, there is nothing to
|
||||
// rename - nil out pair.Dst so the upload below recreates the file at
|
||||
// src.Remote() (the correctly-cased name).
|
||||
if needTransfer {
|
||||
if _, statErr := s.fdst.NewObject(s.ctx, pair.Dst.Remote()); errors.Is(statErr, fs.ErrorObjectNotFound) {
|
||||
fs.Debugf(pair.Dst, "Skipping fix-case rename: destination removed for re-upload, will recreate at %s", src.Remote())
|
||||
pair.Dst = nil
|
||||
}
|
||||
}
|
||||
if pair.Dst != nil {
|
||||
if newDst, err := operations.Move(s.ctx, s.fdst, nil, src.Remote(), pair.Dst); err != nil {
|
||||
fs.Errorf(pair.Dst, "Error while attempting to rename to %s: %v", src.Remote(), err)
|
||||
s.processError(err)
|
||||
} else {
|
||||
fs.Infof(pair.Dst, "Fixed case by renaming to: %s", src.Remote())
|
||||
pair.Dst = newDst
|
||||
}
|
||||
}
|
||||
}
|
||||
if needTransfer {
|
||||
|
||||
Reference in New Issue
Block a user