diff --git a/internal/versioner/simple.go b/internal/versioner/simple.go index d5efea1d..83318b64 100644 --- a/internal/versioner/simple.go +++ b/internal/versioner/simple.go @@ -18,7 +18,6 @@ package versioner import ( "os" "path/filepath" - "sort" "strconv" "github.com/syncthing/syncthing/internal/osutil" @@ -124,10 +123,9 @@ func (v Simple) Archive(filePath string) error { // Use all the found filenames. "~" sorts after "." so all old pattern // files will be deleted before any new, which is as it should be. - versions := append(oldVersions, newVersions...) + versions := uniqueSortedStrings(append(oldVersions, newVersions...)) if len(versions) > v.keep { - sort.Strings(versions) for _, toRemove := range versions[:len(versions)-v.keep] { if debug { l.Debugln("cleaning out", toRemove) diff --git a/internal/versioner/staggered.go b/internal/versioner/staggered.go index c1d55c2b..2f6e09df 100644 --- a/internal/versioner/staggered.go +++ b/internal/versioner/staggered.go @@ -18,7 +18,6 @@ package versioner import ( "os" "path/filepath" - "sort" "strconv" "strings" "sync" @@ -357,9 +356,7 @@ func (v Staggered) Archive(filePath string) error { // Use all the found filenames. versions := append(oldVersions, newVersions...) - - sort.Strings(versions) - v.expire(versions) + v.expire(uniqueSortedStrings(versions)) return nil } diff --git a/internal/versioner/util.go b/internal/versioner/util.go index 5fdc08ce..30eceafe 100644 --- a/internal/versioner/util.go +++ b/internal/versioner/util.go @@ -18,6 +18,7 @@ package versioner import ( "path/filepath" "regexp" + "sort" ) // Inserts ~tag just before the extension of the filename. @@ -40,3 +41,17 @@ func filenameTag(path string) string { } return match[1] } + +func uniqueSortedStrings(strings []string) []string { + seen := make(map[string]struct{}, len(strings)) + unique := make([]string, 0, len(strings)) + for _, str := range strings { + _, ok := seen[str] + if !ok { + seen[str] = struct{}{} + unique = append(unique, str) + } + } + sort.Strings(unique) + return unique +}