1
0
mirror of https://github.com/rclone/rclone.git synced 2025-01-13 20:38:12 +02:00

sync: implement --ignore-errors - fixes #642

This commit is contained in:
Mateusz Pabian 2018-03-13 00:40:19 +01:00 committed by Nick Craig-Wood
parent b52e34ef5e
commit 91b068ad3a
4 changed files with 78 additions and 4 deletions

View File

@ -33,6 +33,7 @@ type ConfigInfo struct {
SizeOnly bool
IgnoreTimes bool
IgnoreExisting bool
IgnoreErrors bool
ModifyWindow time.Duration
Checkers int
Transfers int

View File

@ -43,6 +43,7 @@ func AddFlags(flagSet *pflag.FlagSet) {
flags.BoolVarP(flagSet, &fs.Config.SizeOnly, "size-only", "", fs.Config.SizeOnly, "Skip based on size only, not mod-time or checksum")
flags.BoolVarP(flagSet, &fs.Config.IgnoreTimes, "ignore-times", "I", fs.Config.IgnoreTimes, "Don't skip files that match size and time - transfer all files")
flags.BoolVarP(flagSet, &fs.Config.IgnoreExisting, "ignore-existing", "", fs.Config.IgnoreExisting, "Skip all files that exist on destination")
flags.BoolVarP(flagSet, &fs.Config.IgnoreErrors, "ignore-errors", "", fs.Config.IgnoreErrors, "delete even if there are I/O errors")
flags.BoolVarP(flagSet, &fs.Config.DryRun, "dry-run", "n", fs.Config.DryRun, "Do a trial run with no permanent changes")
flags.DurationVarP(flagSet, &fs.Config.ConnectTimeout, "contimeout", "", fs.Config.ConnectTimeout, "Connect timeout")
flags.DurationVarP(flagSet, &fs.Config.Timeout, "timeout", "", fs.Config.Timeout, "IO idle timeout")

View File

@ -399,7 +399,7 @@ func (s *syncCopyMove) stopDeleters() {
// checkSrcMap is clear then it assumes that the any source files that
// have been found have been removed from dstFiles already.
func (s *syncCopyMove) deleteFiles(checkSrcMap bool) error {
if accounting.Stats.Errored() {
if accounting.Stats.Errored() && !fs.Config.IgnoreErrors {
fs.Errorf(s.fdst, "%v", fs.ErrorNotDeleting)
return fs.ErrorNotDeleting
}
@ -430,7 +430,7 @@ func deleteEmptyDirectories(f fs.Fs, entries fs.DirEntries) error {
if len(entries) == 0 {
return nil
}
if accounting.Stats.Errored() {
if accounting.Stats.Errored() && !fs.Config.IgnoreErrors {
fs.Errorf(f, "%v", fs.ErrorNotDeletingDirs)
return fs.ErrorNotDeletingDirs
}
@ -624,7 +624,7 @@ func (s *syncCopyMove) run() error {
// Delete files after
if s.deleteMode == fs.DeleteModeAfter {
if s.currentError() != nil {
if s.currentError() != nil && !fs.Config.IgnoreErrors {
fs.Errorf(s.fdst, "%v", fs.ErrorNotDeleting)
} else {
s.processError(s.deleteFiles(false))
@ -633,7 +633,7 @@ func (s *syncCopyMove) run() error {
// Prune empty directories
if s.deleteMode != fs.DeleteModeOff {
if s.currentError() != nil {
if s.currentError() != nil && !fs.Config.IgnoreErrors {
fs.Errorf(s.fdst, "%v", fs.ErrorNotDeletingDirs)
} else {
s.processError(deleteEmptyDirectories(s.fdst, s.dstEmptyDirs))

View File

@ -283,6 +283,78 @@ func TestSyncIgnoreExisting(t *testing.T) {
fstest.CheckItems(t, r.Fremote, file1)
}
func TestSyncIgnoreErrors(t *testing.T) {
r := fstest.NewRun(t)
fs.Config.IgnoreErrors = true
defer func() {
fs.Config.IgnoreErrors = false
r.Finalise()
}()
file1 := r.WriteFile("a/potato2", "------------------------------------------------------------", t1)
file2 := r.WriteObject("b/potato", "SMALLER BUT SAME DATE", t2)
file3 := r.WriteBoth("c/non empty space", "AhHa!", t2)
require.NoError(t, operations.Mkdir(r.Fremote, "d"))
fstest.CheckListingWithPrecision(
t,
r.Flocal,
[]fstest.Item{
file1,
file3,
},
[]string{
"a",
"c",
},
fs.Config.ModifyWindow,
)
fstest.CheckListingWithPrecision(
t,
r.Fremote,
[]fstest.Item{
file2,
file3,
},
[]string{
"b",
"c",
"d",
},
fs.Config.ModifyWindow,
)
accounting.Stats.ResetCounters()
fs.CountError(nil)
assert.NoError(t, Sync(r.Fremote, r.Flocal))
fstest.CheckListingWithPrecision(
t,
r.Flocal,
[]fstest.Item{
file1,
file3,
},
[]string{
"a",
"c",
},
fs.Config.ModifyWindow,
)
fstest.CheckListingWithPrecision(
t,
r.Fremote,
[]fstest.Item{
file1,
file3,
},
[]string{
"a",
"c",
},
fs.Config.ModifyWindow,
)
}
func TestSyncAfterChangingModtimeOnly(t *testing.T) {
r := fstest.NewRun(t)
defer r.Finalise()