Fix and document the move command - fixes #334

* Don't attempt to use server side Move unless they are on the same Fs
  * Fix move in the presense of filters
This commit is contained in:
Nick Craig-Wood 2016-02-25 20:05:34 +00:00
parent ccb59480bd
commit d2219a800a
3 changed files with 48 additions and 13 deletions

View File

@ -108,6 +108,22 @@ extended explanation in the `copy` command above if unsure.
If dest:path doesn't exist, it is created and the source:path contents If dest:path doesn't exist, it is created and the source:path contents
go there. go there.
### move source:path dest:path ###
Moves the source to the destination.
If there are no filters in use this is equivalent to a copy followed
by a purge, but may using server side operations to speed it up if
possible.
If filters are in use then it is equivalent to a copy followed by
delete, followed by an rmdir (which only removes the directory if
empty). The individual file moves will be moved with srver side
operations if possible.
**Important**: Since this can cause data loss, test first with the
--dry-run flag.
### rclone ls remote:path ### ### rclone ls remote:path ###
List all the objects in the the path with size and path. List all the objects in the the path with size and path.

View File

@ -354,7 +354,7 @@ func PairMover(in ObjectPairChan, fdst Fs, wg *sync.WaitGroup) {
Stats.Transferring(src) Stats.Transferring(src)
if Config.DryRun { if Config.DryRun {
Log(src, "Not moving as --dry-run") Log(src, "Not moving as --dry-run")
} else if haveMover { } else if haveMover && src.Fs().Name() == fdst.Name() {
// Delete destination if it exists // Delete destination if it exists
if pair.dst != nil { if pair.dst != nil {
err := dst.Remove() err := dst.Remove()
@ -600,8 +600,8 @@ func MoveDir(fdst, fsrc Fs) error {
return nil return nil
} }
// First attempt to use DirMover // First attempt to use DirMover if exists, same Fs and no filters are active
if fdstDirMover, ok := fdst.(DirMover); ok && fsrc.Name() == fdst.Name() { if fdstDirMover, ok := fdst.(DirMover); ok && fsrc.Name() == fdst.Name() && Config.Filter.InActive() {
err := fdstDirMover.DirMove(fsrc) err := fdstDirMover.DirMove(fsrc)
Debug(fdst, "Using server side directory move") Debug(fdst, "Using server side directory move")
switch err { switch err {
@ -623,7 +623,18 @@ func MoveDir(fdst, fsrc Fs) error {
ErrorLog(fdst, "Not deleting files as there were IO errors") ErrorLog(fdst, "Not deleting files as there were IO errors")
return err return err
} }
// If no filters then purge
if Config.Filter.InActive() {
return Purge(fsrc) return Purge(fsrc)
}
// Otherwise remove any remaining files obeying filters
err = Delete(fsrc)
if err != nil {
return err
}
// and try to remove the directory if empty - ignoring error
_ = TryRmdir(fsrc)
return nil
} }
// Check the files in fsrc and fdst according to Size and hash // Check the files in fsrc and fdst according to Size and hash
@ -849,18 +860,24 @@ func Mkdir(f Fs) error {
return nil return nil
} }
// Rmdir removes a container but not if not empty // TryRmdir removes a container but not if not empty. It doesn't
func Rmdir(f Fs) error { // count errors but may return one.
func TryRmdir(f Fs) error {
if Config.DryRun { if Config.DryRun {
Log(f, "Not deleting as dry run is set") Log(f, "Not deleting as dry run is set")
} else { return nil
err := f.Rmdir() }
return f.Rmdir()
}
// Rmdir removes a container but not if not empty
func Rmdir(f Fs) error {
err := TryRmdir(f)
if err != nil { if err != nil {
Stats.Error() Stats.Error()
return err return err
} }
} return err
return nil
} }
// Purge removes a container and all of its contents // Purge removes a container and all of its contents

View File

@ -712,6 +712,7 @@ func TestServerSideMove(t *testing.T) {
fstest.CheckItems(t, fremoteMove, file2) fstest.CheckItems(t, fremoteMove, file2)
// Do server side move // Do server side move
fs.Stats.ResetCounters()
err = fs.MoveDir(fremoteMove, r.fremote) err = fs.MoveDir(fremoteMove, r.fremote)
if err != nil { if err != nil {
t.Fatalf("Server Side Move failed: %v", err) t.Fatalf("Server Side Move failed: %v", err)
@ -721,6 +722,7 @@ func TestServerSideMove(t *testing.T) {
fstest.CheckItems(t, fremoteMove, file2, file1) fstest.CheckItems(t, fremoteMove, file2, file1)
// Move it back again, dst does not exist this time // Move it back again, dst does not exist this time
fs.Stats.ResetCounters()
err = fs.MoveDir(r.fremote, fremoteMove) err = fs.MoveDir(r.fremote, fremoteMove)
if err != nil { if err != nil {
t.Fatalf("Server Side Move 2 failed: %v", err) t.Fatalf("Server Side Move 2 failed: %v", err)