sync: when using --backup-dir don't delete files if we can't set their modtime

This is a problem when syncing a file which just needed its modtime
set with dropbox which can't set the mod time of a file without
re-uploading it.

Before this change we would delete the file, then the server side move
would fail moving the file to the backup-dir because it no longer
existed.

After this change the destination file is moved to the backup-dir
instead of being deleted and the new file is uploaded.

Fixes #2134
This commit is contained in:
Nick Craig-Wood 2018-03-13 16:05:06 +00:00
parent 0c9dc006c5
commit dfd0f4c5a4
3 changed files with 14 additions and 5 deletions

View File

@ -801,7 +801,7 @@ func (o *Object) SetModTime(modTime time.Time) error {
// Dropbox doesn't have a way of doing this so returning this
// error will cause the file to be deleted first then
// re-uploaded to set the time.
return fs.ErrorCantSetModTimeWithoutDelete
return fs.ErrorCantSetModTime
}
// Storable returns whether this object is storable

View File

@ -178,9 +178,13 @@ func equal(src fs.ObjectInfo, dst fs.Object, sizeOnly, checkSum bool) bool {
return false
} else if err == fs.ErrorCantSetModTimeWithoutDelete {
fs.Debugf(dst, "src and dst identical but can't set mod time without deleting and re-uploading")
err = dst.Remove()
if err != nil {
fs.Errorf(dst, "failed to delete before re-upload: %v", err)
// Remove the file if BackupDir isn't set. If BackupDir is set we would rather have the old file
// put in the BackupDir than deleted which is what will happen if we don't delete it.
if fs.Config.BackupDir == "" {
err = dst.Remove()
if err != nil {
fs.Errorf(dst, "failed to delete before re-upload: %v", err)
}
}
return false
} else if err != nil {

View File

@ -246,7 +246,12 @@ func (api *Client) Call(opts *Opts) (resp *http.Response, err error) {
}
if !opts.IgnoreStatus {
if resp.StatusCode < 200 || resp.StatusCode > 299 {
return resp, api.errorHandler(resp)
err = api.errorHandler(resp)
if err.Error() == "" {
// replace empty errors with something
err = errors.Errorf("http error %d: %v", resp.StatusCode, resp.Status)
}
return resp, err
}
}
if opts.NoResponse {