sync: Only allow --track-renames if have a common hash

This commit is contained in:
Nick Craig-Wood 2017-01-02 16:37:59 +00:00
parent 86392fb800
commit 274ab349f4
2 changed files with 27 additions and 18 deletions

View File

@ -417,9 +417,18 @@ The default is `bytes`.
### --track-renames ### ### --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) ### ### --delete-(before,during,after) ###

View File

@ -38,20 +38,6 @@ type syncCopyMove struct {
} }
func newSyncCopyMove(fdst, fsrc Fs, Delete bool, DoMove bool) *syncCopyMove { 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{ s := &syncCopyMove{
fdst: fdst, fdst: fdst,
fsrc: fsrc, fsrc: fsrc,
@ -66,14 +52,28 @@ func newSyncCopyMove(fdst, fsrc Fs, Delete bool, DoMove bool) *syncCopyMove {
toBeChecked: make(ObjectPairChan, Config.Transfers), toBeChecked: make(ObjectPairChan, Config.Transfers),
toBeUploaded: make(ObjectPairChan, Config.Transfers), toBeUploaded: make(ObjectPairChan, Config.Transfers),
deleteBefore: Delete && Config.DeleteBefore, deleteBefore: Delete && Config.DeleteBefore,
trackRenames: canMove && Config.TrackRenames, trackRenames: Config.TrackRenames,
} }
if s.noTraverse && s.Delete { if s.noTraverse && s.Delete {
Debug(s.fdst, "Ignoring --no-traverse with sync") Debug(s.fdst, "Ignoring --no-traverse with sync")
s.noTraverse = false 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 return s
} }
// Check to see if have set the abort flag // Check to see if have set the abort flag