From ced3a4bc19e793d670a8760c5863f4a337d2a32f Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Tue, 22 Mar 2016 17:02:27 +0000 Subject: [PATCH] Implement -I, --ignore-times for unconditional upload - fixes #311 --- docs/content/docs.md | 9 +++++++++ fs/config.go | 3 +++ fs/operations.go | 6 ++++++ fs/operations_test.go | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/docs/content/docs.md b/docs/content/docs.md index aeda5e5d5..19e157be0 100644 --- a/docs/content/docs.md +++ b/docs/content/docs.md @@ -399,6 +399,15 @@ While this isn't a generally recommended option, it can be useful in cases where your files change due to encryption. However, it cannot correct partial transfers in case a transfer was interrupted. +### -I, --ignore-times ### + +Using this option will cause rclone to unconditionally upload all +files regardless of the state of files on the destination. + +Normally rclone would skip any files that have the same +modification time and are the same size (or have the same checksum if +using `--checksum`). + ### --log-file=FILE ### Log all of rclone's output to FILE. This is not active by default. diff --git a/fs/config.go b/fs/config.go index 08181f068..19f625507 100644 --- a/fs/config.go +++ b/fs/config.go @@ -69,6 +69,7 @@ var ( configFile = pflag.StringP("config", "", ConfigPath, "Config file.") checkSum = pflag.BoolP("checksum", "c", false, "Skip based on checksum & size, not mod-time & size") sizeOnly = pflag.BoolP("size-only", "", false, "Skip based on size only, not mod-time or checksum") + ignoreTimes = pflag.BoolP("ignore-times", "I", false, "Don't skip files that match size and time - transfer all files") ignoreExisting = pflag.BoolP("ignore-existing", "", false, "Skip all files that exist on destination") dryRun = pflag.BoolP("dry-run", "n", false, "Do a trial run with no permanent changes") connectTimeout = pflag.DurationP("contimeout", "", 60*time.Second, "Connect timeout") @@ -188,6 +189,7 @@ type ConfigInfo struct { DryRun bool CheckSum bool SizeOnly bool + IgnoreTimes bool IgnoreExisting bool ModifyWindow time.Duration Checkers int @@ -299,6 +301,7 @@ func LoadConfig() { Config.ConnectTimeout = *connectTimeout Config.CheckSum = *checkSum Config.SizeOnly = *sizeOnly + Config.IgnoreTimes = *ignoreTimes Config.IgnoreExisting = *ignoreExisting Config.DumpHeaders = *dumpHeaders Config.DumpBodies = *dumpBodies diff --git a/fs/operations.go b/fs/operations.go index 5a149eb3a..43a65a077 100644 --- a/fs/operations.go +++ b/fs/operations.go @@ -315,6 +315,12 @@ func checkOne(pair ObjectPair, out ObjectPairChan) { Debug(src, "Destination exists, skipping") return } + // If we should upload unconditionally + if Config.IgnoreTimes { + Debug(src, "Uploading unconditionally as --ignore-times is in use") + out <- pair + return + } // If UpdateOlder is in effect, skip if dst is newer than src if Config.UpdateOlder { srcModTime := src.ModTime() diff --git a/fs/operations_test.go b/fs/operations_test.go index 1fb84d301..7b01d0830 100644 --- a/fs/operations_test.go +++ b/fs/operations_test.go @@ -432,6 +432,42 @@ func TestSyncSizeOnly(t *testing.T) { fstest.CheckItems(t, r.fremote, file1) } +func TestSyncIgnoreTimes(t *testing.T) { + r := NewRun(t) + defer r.Finalise() + file1 := r.WriteBoth("existing", "potato", t1) + + fs.Stats.ResetCounters() + err := fs.Sync(r.fremote, r.flocal) + if err != nil { + t.Fatalf("Sync failed: %v", err) + } + + // We should have transferred exactly 0 files because the + // files were identical. + if fs.Stats.GetTransfers() != 0 { + t.Fatalf("Sync 1: want 0 transfer, got %d", fs.Stats.GetTransfers()) + } + + fs.Config.IgnoreTimes = true + defer func() { fs.Config.IgnoreTimes = false }() + + fs.Stats.ResetCounters() + err = fs.Sync(r.fremote, r.flocal) + if err != nil { + t.Fatalf("Sync failed: %v", err) + } + + // We should have transferred exactly one file even though the + // files were identical. + if fs.Stats.GetTransfers() != 1 { + t.Fatalf("Sync 2: want 1 transfer, got %d", fs.Stats.GetTransfers()) + } + + fstest.CheckItems(t, r.flocal, file1) + fstest.CheckItems(t, r.fremote, file1) +} + func TestSyncIgnoreExisting(t *testing.T) { r := NewRun(t) defer r.Finalise()