diff --git a/docs/content/docs.md b/docs/content/docs.md index 721140a49..952aa450c 100644 --- a/docs/content/docs.md +++ b/docs/content/docs.md @@ -417,9 +417,18 @@ The default is `bytes`. ### --track-renames ### -By default renames will be performed as a delete and a copy, which is ineffective for remotes that supports server-side move operations. +By default rclone doesn't not keep track of renamed files, so if you +rename a file locally then sync it to a remote, rclone will delete the +old file on the remote and upload a new copy. -Setting this option will track renames during `sync` and perform renaming server-side. If the destination does not support server-side move, `sync` will fall back to the default behaviour and log an `error` to the console. +If you use this flag, and the remote supports server side copy or +server side move, and the source and destination have a compatible +hash, then this will track renames during `sync`, `copy`, and `move` +operations and perform renaming server-side. + +If the destination does not support server-side copy or move, rclone +will fall back to the default behaviour and log an error level message +to the console. ### --delete-(before,during,after) ### diff --git a/fs/sync.go b/fs/sync.go index 2a64f6b4e..88b573bbd 100644 --- a/fs/sync.go +++ b/fs/sync.go @@ -38,20 +38,6 @@ type syncCopyMove struct { } func newSyncCopyMove(fdst, fsrc Fs, Delete bool, DoMove bool) *syncCopyMove { - - // Don't track renames for remotes without server-side rename support. - // Some remotes simulate rename by server-side copy and delete, so include - // remotes that implements either Mover and Copier. - var canMove bool - switch fdst.(type) { - case Mover, Copier: - canMove = true - } - - if !canMove && Config.TrackRenames { - ErrorLog(nil, "track-renames flag is set, but the destination %q does not support server-side moves", fdst.Name()) - } - s := &syncCopyMove{ fdst: fdst, fsrc: fsrc, @@ -66,14 +52,28 @@ func newSyncCopyMove(fdst, fsrc Fs, Delete bool, DoMove bool) *syncCopyMove { toBeChecked: make(ObjectPairChan, Config.Transfers), toBeUploaded: make(ObjectPairChan, Config.Transfers), deleteBefore: Delete && Config.DeleteBefore, - trackRenames: canMove && Config.TrackRenames, + trackRenames: Config.TrackRenames, } if s.noTraverse && s.Delete { Debug(s.fdst, "Ignoring --no-traverse with sync") s.noTraverse = false } + if s.trackRenames { + // Don't track renames for remotes without server-side rename support. + // Some remotes simulate rename by server-side copy and delete, so include + // remotes that implements either Mover and Copier. + switch fdst.(type) { + case Mover, Copier: + default: + ErrorLog(fdst, "Ignoring --track-renames as the destination does not support server-side move or copy") + s.trackRenames = false + } + if fsrc.Hashes().Overlap(fdst.Hashes()).Count() == 0 { + ErrorLog(fdst, "Ignoring --track-renames as the source and destination do not have a common hash") + s.trackRenames = false + } + } return s - } // Check to see if have set the abort flag