From ae441d31348ab714fbe3e0a09d2bc68847617dec Mon Sep 17 00:00:00 2001 From: Quentin Lemaire Date: Mon, 13 Apr 2020 04:29:13 +0200 Subject: [PATCH 1/5] fix(backup): Switch tags cobra type to handle comma-separated list --- cmd/restic/cmd_backup.go | 4 ++-- internal/archiver/archiver.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/restic/cmd_backup.go b/cmd/restic/cmd_backup.go index a0831b16e..4769654bf 100644 --- a/cmd/restic/cmd_backup.go +++ b/cmd/restic/cmd_backup.go @@ -91,7 +91,7 @@ type BackupOptions struct { ExcludeLargerThan string Stdin bool StdinFilename string - Tags []string + Tags restic.TagList Host string FilesFrom []string TimeStamp string @@ -121,7 +121,7 @@ func init() { f.StringVar(&backupOptions.ExcludeLargerThan, "exclude-larger-than", "", "max `size` of the files to be backed up (allowed suffixes: k/K, m/M, g/G, t/T)") f.BoolVar(&backupOptions.Stdin, "stdin", false, "read backup from stdin") f.StringVar(&backupOptions.StdinFilename, "stdin-filename", "stdin", "`filename` to use when reading from stdin") - f.StringArrayVar(&backupOptions.Tags, "tag", nil, "add a `tag` for the new snapshot (can be specified multiple times)") + f.Var(&backupOptions.Tags, "tag", "add `tags` for the new snapshot in the format `tag[,tag,...]` (can be specified multiple times)") f.StringVarP(&backupOptions.Host, "host", "H", "", "set the `hostname` for the snapshot manually. To prevent an expensive rescan use the \"parent\" flag") f.StringVar(&backupOptions.Host, "hostname", "", "set the `hostname` for the snapshot manually") diff --git a/internal/archiver/archiver.go b/internal/archiver/archiver.go index 42fc03310..367d6e809 100644 --- a/internal/archiver/archiver.go +++ b/internal/archiver/archiver.go @@ -717,7 +717,7 @@ func resolveRelativeTargets(filesys fs.FS, targets []string) ([]string, error) { // SnapshotOptions collect attributes for a new snapshot. type SnapshotOptions struct { - Tags []string + Tags restic.TagList Hostname string Excludes []string Time time.Time From e74110a833d65743c927d21cac6bd84c503163a3 Mon Sep 17 00:00:00 2001 From: Quentin Lemaire Date: Mon, 13 Apr 2020 04:39:50 +0200 Subject: [PATCH 2/5] docs: Write new entry to changelog/unreleased --- changelog/unreleased/issue-2688 | 26 ++++++++++++++++++++++++++ doc/manual_rest.rst | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 changelog/unreleased/issue-2688 diff --git a/changelog/unreleased/issue-2688 b/changelog/unreleased/issue-2688 new file mode 100644 index 000000000..2f6532f57 --- /dev/null +++ b/changelog/unreleased/issue-2688 @@ -0,0 +1,26 @@ +Bugfix: Make backup and tag commands separate tags by comma + +Running `restic backup --tag foo,bar` previously created snapshots with one +single tag containing a comma ("foo,bar") instead of two tags ("foo", "bar"). +Similarly, the `tag` command's --set, --add and --remove options would treat +"foo,bar" as one tag instead of two tags. This was inconsistent with other +commands and often unexpected when one intended "foo,bar" to mean two tags. + +To be consistent in all commands, restic now interprets "foo,bar" to mean two +separate tags ("foo" and "bar") instead of one tag ("foo,bar") everywhere, +including in the `backup` and `tag` commands. + +NOTE: This change might result in unexpected behavior in cases where you use +the `forget` command and filter on tags like "foo,bar". Snapshots previously +backed up with `--tag foo,bar` will still not match that filter, but snapshots +saved from now on will match that filter. + +To replace "foo,bar" tags with "foo" and "bar" tags in old snapshots, you can +first generate a list of the relevant snapshots using a command like +`restic snapshots --json --quiet | jq '.[] | select(contains({tags: ["foo,bar"]})) | .id'` +, and then use `restic tag --set foo --set bar snapshotID [...]` to set the new +tags. Please adjust the commands to real tag names and any additional tags, +as well as the list of snapshots to process. + +https://github.com/restic/restic/issues/2688 +https://github.com/restic/restic/pull/2690 diff --git a/doc/manual_rest.rst b/doc/manual_rest.rst index f84663eab..9b2f9f194 100644 --- a/doc/manual_rest.rst +++ b/doc/manual_rest.rst @@ -105,7 +105,7 @@ command: --parent snapshot use this parent snapshot (default: last snapshot in the repo that has the same target files/directories) --stdin read backup from stdin --stdin-filename filename filename to use when reading from stdin (default "stdin") - --tag tag add a tag for the new snapshot (can be specified multiple times) + --tag tag add `tags` for the new snapshot in the format `tag[,tag,...]` (can be specified multiple times) --time time time of the backup (ex. '2012-11-01 22:08:41') (default: now) --use-fs-snapshot use filesystem snapshot where possible (currently only Windows VSS) --with-atime store the atime for all files and directories From b0882b3f3c9ea334ca3414ab49cd971e80ab26d7 Mon Sep 17 00:00:00 2001 From: Quentin Lemaire Date: Mon, 13 Apr 2020 14:16:02 +0200 Subject: [PATCH 3/5] fix(snapshots): Update help message to better match the 'forget' command one --- cmd/restic/cmd_snapshots.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/restic/cmd_snapshots.go b/cmd/restic/cmd_snapshots.go index 8bc5d5984..300ba99ee 100644 --- a/cmd/restic/cmd_snapshots.go +++ b/cmd/restic/cmd_snapshots.go @@ -47,7 +47,7 @@ func init() { f := cmdSnapshots.Flags() f.StringArrayVarP(&snapshotOptions.Hosts, "host", "H", nil, "only consider snapshots for this `host` (can be specified multiple times)") - f.Var(&snapshotOptions.Tags, "tag", "only consider snapshots which include this `taglist` (can be specified multiple times)") + f.Var(&snapshotOptions.Tags, "tag", "only consider snapshots which include this `taglist` in the format `tag[,tag,...]` (can be specified multiple times)") 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") From a8ad6b9a4b50da8e1d08f7af46003b4b0eeea92e Mon Sep 17 00:00:00 2001 From: Quentin Lemaire Date: Sat, 14 Nov 2020 16:24:58 +0000 Subject: [PATCH 4/5] fix(tags): Change tags list type according to restic.TagList --- cmd/restic/cmd_tag.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/restic/cmd_tag.go b/cmd/restic/cmd_tag.go index 4e1ac46c3..5131cb866 100644 --- a/cmd/restic/cmd_tag.go +++ b/cmd/restic/cmd_tag.go @@ -38,9 +38,9 @@ type TagOptions struct { Hosts []string Paths []string Tags restic.TagLists - SetTags []string - AddTags []string - RemoveTags []string + SetTags restic.TagList + AddTags restic.TagList + RemoveTags restic.TagList } var tagOptions TagOptions @@ -49,9 +49,9 @@ func init() { cmdRoot.AddCommand(cmdTag) tagFlags := cmdTag.Flags() - tagFlags.StringSliceVar(&tagOptions.SetTags, "set", nil, "`tag` which will replace the existing tags (can be given multiple times)") - tagFlags.StringSliceVar(&tagOptions.AddTags, "add", nil, "`tag` which will be added to the existing tags (can be given multiple times)") - tagFlags.StringSliceVar(&tagOptions.RemoveTags, "remove", nil, "`tag` which will be removed from the existing tags (can be given multiple times)") + tagFlags.Var(&tagOptions.SetTags, "set", "`tag` which will replace the existing tags (can be given multiple times)") + tagFlags.Var(&tagOptions.AddTags, "add", "`tag` which will be added to the existing tags (can be given multiple times)") + tagFlags.Var(&tagOptions.RemoveTags, "remove", "`tag` which will be removed from the existing tags (can be given multiple times)") tagFlags.StringArrayVarP(&tagOptions.Hosts, "host", "H", nil, "only consider snapshots for this `host`, when no snapshot ID is given (can be specified multiple times)") tagFlags.Var(&tagOptions.Tags, "tag", "only consider snapshots which include this `taglist`, when no snapshot-ID is given") From fdec8051abff5445c1748a69c92eeea1139b1179 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 14 Nov 2020 22:55:30 +0100 Subject: [PATCH 5/5] tags: Tweak description of --add/set/remove options --- cmd/restic/cmd_tag.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/restic/cmd_tag.go b/cmd/restic/cmd_tag.go index 5131cb866..4ff94b01d 100644 --- a/cmd/restic/cmd_tag.go +++ b/cmd/restic/cmd_tag.go @@ -49,9 +49,9 @@ func init() { cmdRoot.AddCommand(cmdTag) tagFlags := cmdTag.Flags() - tagFlags.Var(&tagOptions.SetTags, "set", "`tag` which will replace the existing tags (can be given multiple times)") - tagFlags.Var(&tagOptions.AddTags, "add", "`tag` which will be added to the existing tags (can be given multiple times)") - tagFlags.Var(&tagOptions.RemoveTags, "remove", "`tag` which will be removed from the existing tags (can be given multiple times)") + tagFlags.Var(&tagOptions.SetTags, "set", "`tags` which will replace the existing tags in the format `tag[,tag,...]` (can be given multiple times)") + tagFlags.Var(&tagOptions.AddTags, "add", "`tags` which will be added to the existing tags in the format `tag[,tag,...]` (can be given multiple times)") + tagFlags.Var(&tagOptions.RemoveTags, "remove", "`tags` which will be removed from the existing tags in the format `tag[,tag,...]` (can be given multiple times)") tagFlags.StringArrayVarP(&tagOptions.Hosts, "host", "H", nil, "only consider snapshots for this `host`, when no snapshot ID is given (can be specified multiple times)") tagFlags.Var(&tagOptions.Tags, "tag", "only consider snapshots which include this `taglist`, when no snapshot-ID is given")