cmd/snapshots: Add option to limit snapshots list

This patch adds a `--latest` option to limit snapshots list to the n
last snapshots. It is very similar to the `--last` one but does not
limit to one entry. It also deprecates the `--last` flag usage in
favor of `--latest 1`

Output example:

    $ restic snapshots --latest 2
    repository 0d3eb989 opened successfully, password is correct
    ID        Time                 Host        Tags        Paths
    ------------------------------------------------------------
    5a33bdcc  2020-12-14 12:30:00  local                   /home
    73887d8e  2020-12-15 12:30:00  local                   /home
    ------------------------------------------------------------
    2 snapshots

Signed-off-by: Sébastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>
This commit is contained in:
Sébastien Gross 2020-12-16 10:09:03 +01:00 committed by Michael Eischer
parent 01261770bb
commit 2a92b68e65
2 changed files with 30 additions and 9 deletions

View file

@ -0,0 +1,9 @@
Enhancement: Allow limiting the snapshots list
The `--last` option allowed limiting the output of the `snapshots`
command to the latest snapshot for each host. The new `--latest n`
option allows limiting the output to the latest `n` snapshots.
This change deprecate `--last` in favour of `--latest 1`
https://github.com/restic/restic/pull/3167

View file

@ -36,7 +36,8 @@ type SnapshotOptions struct {
Tags restic.TagLists
Paths []string
Compact bool
Last bool
Last bool // This option should be removed in favour of Latest.
Latest int
GroupBy string
}
@ -51,6 +52,12 @@ func init() {
f.StringArrayVar(&snapshotOptions.Paths, "path", nil, "only consider snapshots for this `path` (can be specified multiple times)")
f.BoolVarP(&snapshotOptions.Compact, "compact", "c", false, "use compact output format")
f.BoolVar(&snapshotOptions.Last, "last", false, "only show the last snapshot for each host and path")
err := f.MarkDeprecated("last", "use --latest 1")
if err != nil {
// MarkDeprecated only returns an error when the flag is not found
panic(err)
}
f.IntVar(&snapshotOptions.Latest, "latest", 0, "only show the last `n` snapshots for each host and path")
f.StringVarP(&snapshotOptions.GroupBy, "group-by", "g", "", "string for grouping snapshots by host,paths,tags")
}
@ -82,7 +89,11 @@ func runSnapshots(opts SnapshotOptions, gopts GlobalOptions, args []string) erro
for k, list := range snapshotGroups {
if opts.Last {
list = FilterLastSnapshots(list)
// This branch should be removed in the same time
// that --last.
list = FilterLastestSnapshots(list, 1)
} else if opts.Latest > 0 {
list = FilterLastestSnapshots(list, opts.Latest)
}
sort.Sort(sort.Reverse(list))
snapshotGroups[k] = list
@ -125,21 +136,22 @@ func newFilterLastSnapshotsKey(sn *restic.Snapshot) filterLastSnapshotsKey {
return filterLastSnapshotsKey{sn.Hostname, strings.Join(paths, "|")}
}
// FilterLastSnapshots filters a list of snapshots to only return the last
// entry for each hostname and path. If the snapshot contains multiple paths,
// they will be joined and treated as one item.
func FilterLastSnapshots(list restic.Snapshots) restic.Snapshots {
// FilterLastestSnapshots filters a list of snapshots to only return
// the limit last entries for each hostname and path. If the snapshot
// contains multiple paths, they will be joined and treated as one
// item.
func FilterLastestSnapshots(list restic.Snapshots, limit int) restic.Snapshots {
// Sort the snapshots so that the newer ones are listed first
sort.SliceStable(list, func(i, j int) bool {
return list[i].Time.After(list[j].Time)
})
var results restic.Snapshots
seen := make(map[filterLastSnapshotsKey]bool)
seen := make(map[filterLastSnapshotsKey]int)
for _, sn := range list {
key := newFilterLastSnapshotsKey(sn)
if !seen[key] {
seen[key] = true
if seen[key] < limit {
seen[key]++
results = append(results, sn)
}
}