From 326fefcd807182a7fe592e459a3f8ba53edcea4e Mon Sep 17 00:00:00 2001 From: David le Blanc Date: Thu, 15 Jul 2021 11:38:15 +1000 Subject: [PATCH] Allow --tag and --keep-tag to match untagged snapshots --- changelog/unreleased/issue-3456 | 9 +++++++++ doc/060_forget.rst | 9 +++++++++ doc/manual_rest.rst | 18 ++++++++++++------ internal/restic/snapshot.go | 3 +++ internal/restic/snapshot_test.go | 10 ++++++++++ 5 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 changelog/unreleased/issue-3456 diff --git a/changelog/unreleased/issue-3456 b/changelog/unreleased/issue-3456 new file mode 100644 index 000000000..8e69a88f2 --- /dev/null +++ b/changelog/unreleased/issue-3456 @@ -0,0 +1,9 @@ +Enhancement: Support filtering and specifying untagged snapshots + +It was previously not possible to specify an empty tag with the `--tag` and +`--keep-tag` options. This has now been fixed, such that `--tag ''` and +`--keep-tag ''` now matches snapshots without tags. This allows e.g. the +`snapshots` and `forget` commands to only operate on untagged snapshots. + +https://github.com/restic/restic/issues/3456 +https://github.com/restic/restic/pull/3457 diff --git a/doc/060_forget.rst b/doc/060_forget.rst index 1071feb5b..d07f5886c 100644 --- a/doc/060_forget.rst +++ b/doc/060_forget.rst @@ -207,6 +207,8 @@ The ``forget`` command accepts the following parameters: boundaries and not relative to when you run the ``forget`` command. Weeks are Monday 00:00 -> Sunday 23:59, days 00:00 to 23:59, hours :00 to :59, etc. +.. note:: Specifying ``--keep-tag ''`` will match untagged snapshots only. + Multiple policies will be ORed together so as to be as inclusive as possible for keeping snapshots. @@ -234,6 +236,13 @@ To only keep the last snapshot of all snapshots with both the tag ``foo`` and $ restic forget --tag foo,bar --keep-last 1 +To ensure only untagged snapshots are considered, specify the empty string '' as +the tag. + +.. code-block:: console + + $ restic forget --tag '' --keep-last 1 + All the ``--keep-*`` options above only count hours/days/weeks/months/years which have a snapshot, so those without a snapshot are ignored. diff --git a/doc/manual_rest.rst b/doc/manual_rest.rst index 7b7a0adec..0c03d07e6 100644 --- a/doc/manual_rest.rst +++ b/doc/manual_rest.rst @@ -165,12 +165,10 @@ command does that: create exclusive lock for repository modified tags on 1 snapshots -Note the snapshot ID has changed, so between each change we need to look -up the new ID of the snapshot. But there is an even better way, the -``tag`` command accepts ``--tag`` for a filter, so we can filter -snapshots based on the tag we just added. - -So we can add and remove tags incrementally like this: +Note the snapshot ID has changed, so between each change we need to look up the +new ID of the snapshot. But there is an even better way - the ``tag`` command +accepts a filter using the ``--tag`` option, so we can filter snapshots based +on the tag we just added. This way we can add and remove tags incrementally: .. code-block:: console @@ -189,6 +187,14 @@ So we can add and remove tags incrementally like this: $ restic -r /srv/restic-repo tag --tag NL --add SOMETHING no snapshots were modified +To operate on untagged snapshots only, specify the empty string ``''`` as the +filter value to ``--tag``. The following command will add the tag ``OTHER`` +to all untagged snapshots: + +.. code-block:: console + + $ restic -r /srv/restic-repo tag --tag '' --add OTHER + Under the hood -------------- diff --git a/internal/restic/snapshot.go b/internal/restic/snapshot.go index 647bf57e6..ac5f2cf44 100644 --- a/internal/restic/snapshot.go +++ b/internal/restic/snapshot.go @@ -195,6 +195,9 @@ func (sn *Snapshot) hasTag(tag string) bool { // HasTags returns true if the snapshot has all the tags in l. func (sn *Snapshot) HasTags(l []string) bool { for _, tag := range l { + if tag == "" && len(sn.Tags) == 0 { + return true + } if !sn.hasTag(tag) { return false } diff --git a/internal/restic/snapshot_test.go b/internal/restic/snapshot_test.go index 5e1bf8822..efcc00960 100644 --- a/internal/restic/snapshot_test.go +++ b/internal/restic/snapshot_test.go @@ -14,3 +14,13 @@ func TestNewSnapshot(t *testing.T) { _, err := restic.NewSnapshot(paths, nil, "foo", time.Now()) rtest.OK(t, err) } + +func TestTagList(t *testing.T) { + paths := []string{"/home/foobar"} + tags := []string{""} + + sn, _ := restic.NewSnapshot(paths, nil, "foo", time.Now()) + + r := sn.HasTags(tags) + rtest.Assert(t, r, "Failed to match untagged snapshot") +}