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:
parent
b52e34ef5e
commit
91b068ad3a
@ -33,6 +33,7 @@ type ConfigInfo struct {
|
||||
SizeOnly bool
|
||||
IgnoreTimes bool
|
||||
IgnoreExisting bool
|
||||
IgnoreErrors bool
|
||||
ModifyWindow time.Duration
|
||||
Checkers int
|
||||
Transfers int
|
||||
|
@ -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")
|
||||
|
@ -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))
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user