Merge pull request #2690 from SkYNewZ/master

Fix #2688: Handle comma-separated list tags when using backup command
This commit is contained in:
MichaelEischer 2020-11-14 23:19:42 +01:00 committed by GitHub
commit 3601a9b6cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 37 additions and 11 deletions

View file

@ -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

View file

@ -91,7 +91,7 @@ type BackupOptions struct {
ExcludeLargerThan string ExcludeLargerThan string
Stdin bool Stdin bool
StdinFilename string StdinFilename string
Tags []string Tags restic.TagList
Host string Host string
FilesFrom []string FilesFrom []string
TimeStamp 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.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.BoolVar(&backupOptions.Stdin, "stdin", false, "read backup from stdin")
f.StringVar(&backupOptions.StdinFilename, "stdin-filename", "stdin", "`filename` to use when reading 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.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") f.StringVar(&backupOptions.Host, "hostname", "", "set the `hostname` for the snapshot manually")

View file

@ -47,7 +47,7 @@ func init() {
f := cmdSnapshots.Flags() f := cmdSnapshots.Flags()
f.StringArrayVarP(&snapshotOptions.Hosts, "host", "H", nil, "only consider snapshots for this `host` (can be specified multiple times)") 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.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.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") f.BoolVar(&snapshotOptions.Last, "last", false, "only show the last snapshot for each host and path")

View file

@ -38,9 +38,9 @@ type TagOptions struct {
Hosts []string Hosts []string
Paths []string Paths []string
Tags restic.TagLists Tags restic.TagLists
SetTags []string SetTags restic.TagList
AddTags []string AddTags restic.TagList
RemoveTags []string RemoveTags restic.TagList
} }
var tagOptions TagOptions var tagOptions TagOptions
@ -49,9 +49,9 @@ func init() {
cmdRoot.AddCommand(cmdTag) cmdRoot.AddCommand(cmdTag)
tagFlags := cmdTag.Flags() tagFlags := cmdTag.Flags()
tagFlags.StringSliceVar(&tagOptions.SetTags, "set", nil, "`tag` which will replace 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.StringSliceVar(&tagOptions.AddTags, "add", nil, "`tag` which will be added to the existing tags (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.StringSliceVar(&tagOptions.RemoveTags, "remove", nil, "`tag` which will be removed from the existing tags (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.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") tagFlags.Var(&tagOptions.Tags, "tag", "only consider snapshots which include this `taglist`, when no snapshot-ID is given")

View file

@ -105,7 +105,7 @@ command:
--parent snapshot use this parent snapshot (default: last snapshot in the repo that has the same target files/directories) --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 read backup from stdin
--stdin-filename filename filename to use when reading from stdin (default "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) --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) --use-fs-snapshot use filesystem snapshot where possible (currently only Windows VSS)
--with-atime store the atime for all files and directories --with-atime store the atime for all files and directories

View file

@ -717,7 +717,7 @@ func resolveRelativeTargets(filesys fs.FS, targets []string) ([]string, error) {
// SnapshotOptions collect attributes for a new snapshot. // SnapshotOptions collect attributes for a new snapshot.
type SnapshotOptions struct { type SnapshotOptions struct {
Tags []string Tags restic.TagList
Hostname string Hostname string
Excludes []string Excludes []string
Time time.Time Time time.Time