From 25f22ec561272db5654dba693d6845f21a41b94a Mon Sep 17 00:00:00 2001 From: klauspost Date: Tue, 5 Jan 2016 11:35:36 +0100 Subject: [PATCH] Add "--ignore-existing" flag. Add option to completely ignore existing files and not consider them for transfer. Fixes #274 --- docs/content/docs.md | 9 +++++++++ fs/config.go | 3 +++ fs/operations.go | 5 +++++ fs/operations_test.go | 25 +++++++++++++++++++++++++ 4 files changed, 42 insertions(+) diff --git a/docs/content/docs.md b/docs/content/docs.md index 5b6591d4a..e1e760375 100644 --- a/docs/content/docs.md +++ b/docs/content/docs.md @@ -253,6 +253,15 @@ modification times in the same way as rclone. When using this flag, rclone won't update mtimes of remote files if they are incorrect as it would normally. +### --ignore-existing ### + +Using this option will make rclone unconditionally skip all files +that exist on the destination, no matter the content of these files. + +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. + ### --stats=TIME ### Rclone will print stats at regular intervals to show its progress. diff --git a/fs/config.go b/fs/config.go index 155f310e5..7b6fb4c9e 100644 --- a/fs/config.go +++ b/fs/config.go @@ -62,6 +62,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") + 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") timeout = pflag.DurationP("timeout", "", 5*60*time.Second, "IO idle timeout") @@ -168,6 +169,7 @@ type ConfigInfo struct { DryRun bool CheckSum bool SizeOnly bool + IgnoreExisting bool ModifyWindow time.Duration Checkers int Transfers int @@ -261,6 +263,7 @@ func LoadConfig() { Config.ConnectTimeout = *connectTimeout Config.CheckSum = *checkSum Config.SizeOnly = *sizeOnly + Config.IgnoreExisting = *ignoreExisting Config.DumpHeaders = *dumpHeaders Config.DumpBodies = *dumpBodies Config.InsecureSkipVerify = *skipVerify diff --git a/fs/operations.go b/fs/operations.go index 11df40344..bd3739996 100644 --- a/fs/operations.go +++ b/fs/operations.go @@ -281,6 +281,11 @@ func checkOne(pair ObjectPair, out ObjectPairChan) { if !src.Storable() { return } + // If we should ignore existing files, don't transfer + if Config.IgnoreExisting { + Debug(src, "Destination exists, skipping") + return + } // Check to see if changed or not if Equal(src, dst) { Debug(src, "Unchanged skipping") diff --git a/fs/operations_test.go b/fs/operations_test.go index 97026ccc4..661829134 100644 --- a/fs/operations_test.go +++ b/fs/operations_test.go @@ -294,6 +294,31 @@ func TestSyncSizeOnly(t *testing.T) { cleanTempDir(t) } +func TestSyncIgnoreExisting(t *testing.T) { + WriteFile("existing", "potato", t1) + fs.Config.IgnoreExisting = true + defer func() { fs.Config.IgnoreExisting = false }() + err := fs.Sync(fremote, flocal) + if err != nil { + t.Fatalf("Sync failed: %v", err) + } + items := []fstest.Item{ + {Path: "existing", Size: 6, ModTime: t1, Md5sum: "8ee2027983915ec78acc45027d874316"}, + } + fstest.CheckListingWithPrecision(t, flocal, items, fs.Config.ModifyWindow) + fstest.CheckListingWithPrecision(t, fremote, items, fs.Config.ModifyWindow) + + // Change everything + WriteFile("existing", "newpotatoes", t2) + err = fs.Sync(fremote, flocal) + if err != nil { + t.Fatalf("Sync failed: %v", err) + } + // Items should not change + fstest.CheckListingWithPrecision(t, fremote, items, fs.Config.ModifyWindow) + cleanTempDir(t) +} + func TestSyncAfterChangingModtimeOnly(t *testing.T) { WriteFile("empty space", "", t1)