func TestDeduplicateRename(t *testing.T) { if *RemoteName != "TestDrive:" { t.Skip("Can only test deduplicate on google drive") } r := NewRun(t) defer r.Finalise() file1 := r.WriteUncheckedObject("one.txt", "This is one", t1) file2 := r.WriteUncheckedObject("one.txt", "This is one too", t2) file3 := r.WriteUncheckedObject("one.txt", "This is another one", t3) r.checkWithDuplicates(t, file1, file2, file3) err := fs.Deduplicate(r.fremote, fs.DeduplicateRename) require.NoError(t, err) list := fs.NewLister().Start(r.fremote, "") for { o, err := list.GetObject() require.NoError(t, err) // Check if we are finished if o == nil { break } remote := o.Remote() if remote != "one-1.txt" && remote != "one-2.txt" && remote != "one-3.txt" { t.Errorf("Bad file name after rename %q", remote) } size := o.Size() if size != file1.Size && size != file2.Size && size != file3.Size { t.Errorf("Size not one of the object sizes %d", size) } } }
func TestDeduplicateOldest(t *testing.T) { r := NewRun(t) defer r.Finalise() skipIfCantDedupe(t, r.fremote) file1 := r.WriteUncheckedObject("one", "This is one", t1) file2 := r.WriteUncheckedObject("one", "This is one too", t2) file3 := r.WriteUncheckedObject("one", "This is another one", t3) r.checkWithDuplicates(t, file1, file2, file3) err := fs.Deduplicate(r.fremote, fs.DeduplicateOldest) require.NoError(t, err) fstest.CheckItems(t, r.fremote, file1) }
func TestDeduplicateOldest(t *testing.T) { if *RemoteName != "TestDrive:" { t.Skip("Can only test deduplicate on google drive") } r := NewRun(t) defer r.Finalise() file1 := r.WriteUncheckedObject("one", "This is one", t1) file2 := r.WriteUncheckedObject("one", "This is one too", t2) file3 := r.WriteUncheckedObject("one", "This is another one", t3) r.checkWithDuplicates(t, file1, file2, file3) err := fs.Deduplicate(r.fremote, fs.DeduplicateOldest) require.NoError(t, err) fstest.CheckItems(t, r.fremote, file1) }
func TestDeduplicateFirst(t *testing.T) { r := NewRun(t) defer r.Finalise() skipIfCantDedupe(t, r.fremote) file1 := r.WriteUncheckedObject("one", "This is one", t1) file2 := r.WriteUncheckedObject("one", "This is one A", t1) file3 := r.WriteUncheckedObject("one", "This is one BB", t1) r.checkWithDuplicates(t, file1, file2, file3) err := fs.Deduplicate(r.fremote, fs.DeduplicateFirst) require.NoError(t, err) objects, size, err := fs.Count(r.fremote) require.NoError(t, err) assert.Equal(t, int64(1), objects) if size != file1.Size && size != file2.Size && size != file3.Size { t.Errorf("Size not one of the object sizes %d", size) } }
func TestDeduplicateFirst(t *testing.T) { if *RemoteName != "TestDrive:" { t.Skip("Can only test deduplicate on google drive") } r := NewRun(t) defer r.Finalise() file1 := r.WriteUncheckedObject("one", "This is one", t1) file2 := r.WriteUncheckedObject("one", "This is one A", t1) file3 := r.WriteUncheckedObject("one", "This is one BB", t1) r.checkWithDuplicates(t, file1, file2, file3) err := fs.Deduplicate(r.fremote, fs.DeduplicateFirst) require.NoError(t, err) objects, size, err := fs.Count(r.fremote) require.NoError(t, err) assert.Equal(t, 1, objects) if size != file1.Size && size != file2.Size && size != file3.Size { t.Errorf("Size not one of the object sizes %d", size) } }
* ` + "`" + `--dedupe-mode interactive` + "`" + ` - interactive as above. * ` + "`" + `--dedupe-mode skip` + "`" + ` - removes identical files then skips anything left. * ` + "`" + `--dedupe-mode first` + "`" + ` - removes identical files then keeps the first one. * ` + "`" + `--dedupe-mode newest` + "`" + ` - removes identical files then keeps the newest one. * ` + "`" + `--dedupe-mode oldest` + "`" + ` - removes identical files then keeps the oldest one. * ` + "`" + `--dedupe-mode rename` + "`" + ` - removes identical files then renames the rest to be different. For example to rename all the identically named photos in your Google Photos directory, do rclone dedupe --dedupe-mode rename "drive:Google Photos" Or rclone dedupe rename "drive:Google Photos" `, Run: func(command *cobra.Command, args []string) { cmd.CheckArgs(1, 2, command, args) if len(args) > 1 { err := dedupeMode.Set(args[0]) if err != nil { log.Fatal(err) } args = args[1:] } fdst := cmd.NewFsSrc(args) cmd.Run(false, command, func() error { return fs.Deduplicate(fdst, dedupeMode) }) }, }
don't match. It doesn't alter the source or destination.`, Run: func(fdst, fsrc fs.Fs) error { return fs.Check(fdst, fsrc) }, MinArgs: 2, MaxArgs: 2, }, { Name: "dedupe", ArgsHelp: "remote:path", Help: ` Interactively find duplicate files and offer to delete all but one or rename them to be different. Only useful with Google Drive which can have duplicate file names.`, Run: func(fdst, fsrc fs.Fs) error { return fs.Deduplicate(fdst, fs.Config.DedupeMode) }, MinArgs: 1, MaxArgs: 1, }, { Name: "config", Help: ` Enter an interactive configuration session.`, Run: func(fdst, fsrc fs.Fs) error { fs.EditConfig() return nil }, NoStats: true, }, {
don't match. It doesn't alter the source or destination.`, Run: func(fdst, fsrc fs.Fs) error { return fs.Check(fdst, fsrc) }, MinArgs: 2, MaxArgs: 2, }, { Name: "dedupe", ArgsHelp: "remote:path", Help: ` Interactively find duplicate files and offer to delete all but one or rename them to be different. Only useful with Google Drive which can have duplicate file names.`, Run: func(fdst, fsrc fs.Fs) error { return fs.Deduplicate(fdst) }, MinArgs: 1, MaxArgs: 1, }, { Name: "config", Help: ` Enter an interactive configuration session.`, Run: func(fdst, fsrc fs.Fs) error { fs.EditConfig() return nil }, NoStats: true, }, {