fs: move with --ignore-existing will not delete skipped files - #5463
This commit is contained in:
parent
3d9da896d2
commit
c32d5dd1f3
5 changed files with 96 additions and 1 deletions
|
@ -910,6 +910,10 @@ While this isn't a generally recommended option, it can be useful
|
||||||
in cases where your files change due to encryption. However, it cannot
|
in cases where your files change due to encryption. However, it cannot
|
||||||
correct partial transfers in case a transfer was interrupted.
|
correct partial transfers in case a transfer was interrupted.
|
||||||
|
|
||||||
|
When performing a `move`/`moveto` command, this flag will leave skipped
|
||||||
|
files in the source location unchanged when a file with the same name
|
||||||
|
exists on the destination.
|
||||||
|
|
||||||
### --ignore-size ###
|
### --ignore-size ###
|
||||||
|
|
||||||
Normally rclone will look at modification time and size of files to
|
Normally rclone will look at modification time and size of files to
|
||||||
|
|
|
@ -1811,7 +1811,11 @@ func moveOrCopyFile(ctx context.Context, fdst fs.Fs, fsrc fs.Fs, dstFileName str
|
||||||
} else {
|
} else {
|
||||||
tr := accounting.Stats(ctx).NewCheckingTransfer(srcObj)
|
tr := accounting.Stats(ctx).NewCheckingTransfer(srcObj)
|
||||||
if !cp {
|
if !cp {
|
||||||
err = DeleteFile(ctx, srcObj)
|
if ci.IgnoreExisting {
|
||||||
|
fs.Debugf(srcObj, "Not removing source file as destination file exists and --ignore-existing is set")
|
||||||
|
} else {
|
||||||
|
err = DeleteFile(ctx, srcObj)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tr.Done(ctx, err)
|
tr.Done(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -811,6 +811,32 @@ func TestMoveFile(t *testing.T) {
|
||||||
fstest.CheckItems(t, r.Fremote, file2)
|
fstest.CheckItems(t, r.Fremote, file2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMoveFileWithIgnoreExisting(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx, ci := fs.AddConfig(ctx)
|
||||||
|
r := fstest.NewRun(t)
|
||||||
|
defer r.Finalise()
|
||||||
|
file1 := r.WriteFile("file1", "file1 contents", t1)
|
||||||
|
fstest.CheckItems(t, r.Flocal, file1)
|
||||||
|
|
||||||
|
ci.IgnoreExisting = true
|
||||||
|
|
||||||
|
err := operations.MoveFile(ctx, r.Fremote, r.Flocal, file1.Path, file1.Path)
|
||||||
|
require.NoError(t, err)
|
||||||
|
fstest.CheckItems(t, r.Flocal)
|
||||||
|
fstest.CheckItems(t, r.Fremote, file1)
|
||||||
|
|
||||||
|
// Recreate file with updated content
|
||||||
|
file1b := r.WriteFile("file1", "file1 modified", t2)
|
||||||
|
fstest.CheckItems(t, r.Flocal, file1b)
|
||||||
|
|
||||||
|
// Ensure modified file did not transfer and was not deleted
|
||||||
|
err = operations.MoveFile(ctx, r.Fremote, r.Flocal, file1.Path, file1b.Path)
|
||||||
|
require.NoError(t, err)
|
||||||
|
fstest.CheckItems(t, r.Flocal, file1b)
|
||||||
|
fstest.CheckItems(t, r.Fremote, file1)
|
||||||
|
}
|
||||||
|
|
||||||
func TestCaseInsensitiveMoveFile(t *testing.T) {
|
func TestCaseInsensitiveMoveFile(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
r := fstest.NewRun(t)
|
r := fstest.NewRun(t)
|
||||||
|
|
|
@ -354,6 +354,8 @@ func (s *syncCopyMove) pairChecker(in *pipe, out *pipe, fraction int, wg *sync.W
|
||||||
// Delete src if no error on copy
|
// Delete src if no error on copy
|
||||||
if operations.SameObject(src, pair.Dst) {
|
if operations.SameObject(src, pair.Dst) {
|
||||||
fs.Logf(src, "Not removing source file as it is the same file as the destination")
|
fs.Logf(src, "Not removing source file as it is the same file as the destination")
|
||||||
|
} else if s.ci.IgnoreExisting {
|
||||||
|
fs.Debugf(src, "Not removing source file as destination file exists and --ignore-existing is set")
|
||||||
} else {
|
} else {
|
||||||
s.processError(operations.DeleteFile(s.ctx, src))
|
s.processError(operations.DeleteFile(s.ctx, src))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1342,6 +1342,65 @@ func TestMoveWithoutDeleteEmptySrcDirs(t *testing.T) {
|
||||||
fstest.CheckItems(t, r.Fremote, file1, file2)
|
fstest.CheckItems(t, r.Fremote, file1, file2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMoveWithIgnoreExisting(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
ctx, ci := fs.AddConfig(ctx)
|
||||||
|
r := fstest.NewRun(t)
|
||||||
|
defer r.Finalise()
|
||||||
|
file1 := r.WriteFile("existing", "potato", t1)
|
||||||
|
file2 := r.WriteFile("existing-b", "tomato", t1)
|
||||||
|
|
||||||
|
ci.IgnoreExisting = true
|
||||||
|
|
||||||
|
accounting.GlobalStats().ResetCounters()
|
||||||
|
err := MoveDir(ctx, r.Fremote, r.Flocal, false, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
fstest.CheckListingWithPrecision(
|
||||||
|
t,
|
||||||
|
r.Flocal,
|
||||||
|
[]fstest.Item{},
|
||||||
|
[]string{},
|
||||||
|
fs.GetModifyWindow(ctx, r.Flocal),
|
||||||
|
)
|
||||||
|
fstest.CheckListingWithPrecision(
|
||||||
|
t,
|
||||||
|
r.Fremote,
|
||||||
|
[]fstest.Item{
|
||||||
|
file1,
|
||||||
|
file2,
|
||||||
|
},
|
||||||
|
[]string{},
|
||||||
|
fs.GetModifyWindow(ctx, r.Fremote),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Recreate first file with modified content
|
||||||
|
file1b := r.WriteFile("existing", "newpotatoes", t2)
|
||||||
|
accounting.GlobalStats().ResetCounters()
|
||||||
|
err = MoveDir(ctx, r.Fremote, r.Flocal, false, false)
|
||||||
|
require.NoError(t, err)
|
||||||
|
// Source items should still exist in modified state
|
||||||
|
fstest.CheckListingWithPrecision(
|
||||||
|
t,
|
||||||
|
r.Flocal,
|
||||||
|
[]fstest.Item{
|
||||||
|
file1b,
|
||||||
|
},
|
||||||
|
[]string{},
|
||||||
|
fs.GetModifyWindow(ctx, r.Flocal),
|
||||||
|
)
|
||||||
|
// Dest items should not have changed
|
||||||
|
fstest.CheckListingWithPrecision(
|
||||||
|
t,
|
||||||
|
r.Fremote,
|
||||||
|
[]fstest.Item{
|
||||||
|
file1,
|
||||||
|
file2,
|
||||||
|
},
|
||||||
|
[]string{},
|
||||||
|
fs.GetModifyWindow(ctx, r.Fremote),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Test a server-side move if possible, or the backup path if not
|
// Test a server-side move if possible, or the backup path if not
|
||||||
func TestServerSideMove(t *testing.T) {
|
func TestServerSideMove(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
Loading…
Reference in a new issue