From 724120d2f3a46be5fe51a8d6179f081cb5032602 Mon Sep 17 00:00:00 2001
From: Nick Craig-Wood <nick@craig-wood.com>
Date: Mon, 26 Feb 2018 12:55:05 +0000
Subject: [PATCH] local: make DirMove return fs.ErrorCantDirMove to allow
 fallback

Before this change `rclone move localdir /mnt/different-fs` would
error.  Now it falls back to moving individual files, which in turn
falls back to copying individual files across the filesystem boundary.
---
 backend/local/local.go | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/backend/local/local.go b/backend/local/local.go
index f01493a3b..0b70c0dc8 100644
--- a/backend/local/local.go
+++ b/backend/local/local.go
@@ -535,7 +535,20 @@ func (f *Fs) DirMove(src fs.Fs, srcRemote, dstRemote string) error {
 	}
 
 	// Do the move
-	return os.Rename(srcPath, dstPath)
+	err = os.Rename(srcPath, dstPath)
+	if os.IsNotExist(err) {
+		// race condition, source was deleted in the meantime
+		return err
+	} else if os.IsPermission(err) {
+		// not enough rights to write to dst
+		return err
+	} else if err != nil {
+		// not quite clear, but probably trying to move directory across file system
+		// boundaries. Copying might still work.
+		fs.Errorf(src, "Can't move dir: %v: trying copy", err)
+		return fs.ErrorCantDirMove
+	}
+	return nil
 }
 
 // Hashes returns the supported hash sets.