mirror of
https://github.com/restic/restic.git
synced 2026-05-28 04:35:41 -04:00
Merge 13cb18f8ad into f000da3b35
This commit is contained in:
commit
12aff9d537
4 changed files with 33 additions and 0 deletions
7
changelog/unreleased/issue-5157
Normal file
7
changelog/unreleased/issue-5157
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Enhancement: Added `--keep-unique` flag to `forget` command
|
||||
|
||||
Restic `forget` command can now remove duplicate snapshots with the
|
||||
`--keep-unique` flag set.
|
||||
|
||||
https://github.com/restic/restic/issues/5157
|
||||
https://github.com/restic/restic/pull/5364
|
||||
|
|
@ -112,6 +112,7 @@ type ForgetOptions struct {
|
|||
WithinMonthly data.Duration
|
||||
WithinYearly data.Duration
|
||||
KeepTags data.TagLists
|
||||
Unique bool
|
||||
|
||||
UnsafeAllowRemoveAll bool
|
||||
|
||||
|
|
@ -138,6 +139,7 @@ func (opts *ForgetOptions) AddFlags(f *pflag.FlagSet) {
|
|||
f.VarP(&opts.WithinMonthly, "keep-within-monthly", "", "keep monthly snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
|
||||
f.VarP(&opts.WithinYearly, "keep-within-yearly", "", "keep yearly snapshots that are newer than `duration` (eg. 1y5m7d2h) relative to the latest snapshot")
|
||||
f.Var(&opts.KeepTags, "keep-tag", "keep snapshots with this `taglist` (can be specified multiple times)")
|
||||
f.BoolVar(&opts.Unique, "keep-unique", false, "keep the only one snapshot per tree")
|
||||
f.BoolVar(&opts.UnsafeAllowRemoveAll, "unsafe-allow-remove-all", false, "allow deleting all snapshots of a snapshot group")
|
||||
|
||||
f.StringArrayVar(&opts.Hosts, "hostname", nil, "only consider snapshots with the given `hostname` (can be specified multiple times)")
|
||||
|
|
@ -233,6 +235,7 @@ func runForget(ctx context.Context, opts ForgetOptions, pruneOptions PruneOption
|
|||
WithinMonthly: opts.WithinMonthly,
|
||||
WithinYearly: opts.WithinYearly,
|
||||
Tags: opts.KeepTags,
|
||||
Unique: opts.Unique,
|
||||
}
|
||||
|
||||
if policy.Empty() {
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@ The ``forget`` command accepts the following policy options:
|
|||
specified duration of the latest snapshot.
|
||||
- ``--keep-within-yearly duration`` keep all yearly snapshots made within the
|
||||
specified duration of the latest snapshot.
|
||||
- ``--keep-unique`` keep only one snapshot per tree.
|
||||
|
||||
.. note:: All calendar related options (``--keep-{hourly,daily,...}``) work on
|
||||
natural time boundaries and *not* relative to when you run ``forget``. Weeks
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/restic/restic/internal/debug"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
)
|
||||
|
||||
// ExpirePolicy configures which snapshots should be automatically removed.
|
||||
|
|
@ -25,6 +26,7 @@ type ExpirePolicy struct {
|
|||
WithinMonthly Duration // keep monthly snapshots made within this duration
|
||||
WithinYearly Duration // keep yearly snapshots made within this duration
|
||||
Tags []TagList // keep all snapshots that include at least one of the tag lists.
|
||||
Unique bool // keep the only one snapshot per tree
|
||||
}
|
||||
|
||||
func (e ExpirePolicy) String() (s string) {
|
||||
|
|
@ -164,6 +166,15 @@ func findLatestTimestamp(list Snapshots) time.Time {
|
|||
return latest
|
||||
}
|
||||
|
||||
func findParentSnapshot(list Snapshots, id restic.ID) *Snapshot {
|
||||
for _, sn := range list {
|
||||
if sn.ID().Equal(id) {
|
||||
return sn
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// KeepReason specifies why a particular snapshot was kept, and the counters at
|
||||
// that point in the policy evaluation.
|
||||
type KeepReason struct {
|
||||
|
|
@ -288,6 +299,17 @@ func ApplyPolicy(list Snapshots, p ExpirePolicy) (keep, remove Snapshots, reason
|
|||
}
|
||||
}
|
||||
|
||||
if p.Unique {
|
||||
if cur.Parent != nil {
|
||||
parent := findParentSnapshot(keep, *cur.Parent)
|
||||
if parent != nil {
|
||||
if parent.Tree == cur.Tree {
|
||||
keepSnap = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if keepSnap {
|
||||
keep = append(keep, cur)
|
||||
kr := KeepReason{
|
||||
|
|
|
|||
Loading…
Reference in a new issue