mirror of
https://github.com/rclone/rclone.git
synced 2026-05-12 10:03:35 -04:00
sync: fix --fix-case rename failing on backends that can't update modtime
When --fix-case was used (e.g. by bisync) on backends that can't set modification times in place - such as Dropbox - files whose content matched but whose modtimes differed would fail to rename with a "from_lookup/not_found" error and abort the operation. This happened because operations.NeedTransfer was called before the fix-case rename. NeedTransfer's equality check would delete the destination as a precursor to re-uploading it (the standard way to update a modtime on these backends), so by the time the rename ran the file no longer existed on the remote. Fix by running the fix-case rename first, so that any subsequent delete/re-upload happens at the correctly-cased destination path. See: #8881
This commit is contained in:
@@ -380,6 +380,20 @@ func (s *syncCopyMove) pairChecker(in *pipe, out *pipe, fraction int, wg *sync.W
|
||||
tr := accounting.Stats(s.ctx).NewCheckingTransfer(src, "checking")
|
||||
// Check to see if can store this
|
||||
if src.Storable() {
|
||||
// Fix case for case insensitive filesystems before checking
|
||||
// whether a transfer is needed, since NeedTransfer may delete
|
||||
// the destination (when content matches but modtime can't be
|
||||
// set without re-upload), which would cause the rename below
|
||||
// to fail with a "not found" error.
|
||||
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
|
||||
}
|
||||
}
|
||||
needTransfer := operations.NeedTransfer(s.ctx, pair.Dst, pair.Src)
|
||||
if needTransfer {
|
||||
NoNeedTransfer, err := operations.CompareOrCopyDest(s.ctx, s.fdst, pair.Dst, pair.Src, s.compareCopyDest, s.backupDir)
|
||||
@@ -391,16 +405,6 @@ func (s *syncCopyMove) pairChecker(in *pipe, out *pipe, fraction int, wg *sync.W
|
||||
needTransfer = false
|
||||
}
|
||||
}
|
||||
// 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 needTransfer {
|
||||
// If files are treated as immutable, fail if destination exists and does not match
|
||||
if s.ci.Immutable && pair.Dst != nil {
|
||||
|
||||
Reference in New Issue
Block a user