mirror of https://github.com/restic/restic.git
Add iexclude and iinclude options to restore command
This commit is contained in:
parent
db82e6b80c
commit
c13f79da02
|
@ -28,13 +28,15 @@ repository.
|
||||||
|
|
||||||
// RestoreOptions collects all options for the restore command.
|
// RestoreOptions collects all options for the restore command.
|
||||||
type RestoreOptions struct {
|
type RestoreOptions struct {
|
||||||
Exclude []string
|
Exclude []string
|
||||||
Include []string
|
InsensitiveExclude []string
|
||||||
Target string
|
Include []string
|
||||||
Host string
|
InsensitiveInclude []string
|
||||||
Paths []string
|
Target string
|
||||||
Tags restic.TagLists
|
Host string
|
||||||
Verify bool
|
Paths []string
|
||||||
|
Tags restic.TagLists
|
||||||
|
Verify bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var restoreOptions RestoreOptions
|
var restoreOptions RestoreOptions
|
||||||
|
@ -44,7 +46,9 @@ func init() {
|
||||||
|
|
||||||
flags := cmdRestore.Flags()
|
flags := cmdRestore.Flags()
|
||||||
flags.StringArrayVarP(&restoreOptions.Exclude, "exclude", "e", nil, "exclude a `pattern` (can be specified multiple times)")
|
flags.StringArrayVarP(&restoreOptions.Exclude, "exclude", "e", nil, "exclude a `pattern` (can be specified multiple times)")
|
||||||
|
flags.StringArrayVar(&restoreOptions.InsensitiveExclude, "iexclude", nil, "same as `--exclude` but ignores the casing of filenames")
|
||||||
flags.StringArrayVarP(&restoreOptions.Include, "include", "i", nil, "include a `pattern`, exclude everything else (can be specified multiple times)")
|
flags.StringArrayVarP(&restoreOptions.Include, "include", "i", nil, "include a `pattern`, exclude everything else (can be specified multiple times)")
|
||||||
|
flags.StringArrayVar(&restoreOptions.InsensitiveInclude, "iinclude", nil, "same as `--include` but ignores the casing of filenames")
|
||||||
flags.StringVarP(&restoreOptions.Target, "target", "t", "", "directory to extract data to")
|
flags.StringVarP(&restoreOptions.Target, "target", "t", "", "directory to extract data to")
|
||||||
|
|
||||||
flags.StringVarP(&restoreOptions.Host, "host", "H", "", `only consider snapshots for this host when the snapshot ID is "latest"`)
|
flags.StringVarP(&restoreOptions.Host, "host", "H", "", `only consider snapshots for this host when the snapshot ID is "latest"`)
|
||||||
|
@ -55,6 +59,8 @@ func init() {
|
||||||
|
|
||||||
func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
|
func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
|
||||||
ctx := gopts.ctx
|
ctx := gopts.ctx
|
||||||
|
hasExcludes := len(opts.Exclude) > 0 || len(opts.InsensitiveExclude) > 0
|
||||||
|
hasIncludes := len(opts.Include) > 0 || len(opts.InsensitiveInclude) > 0
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case len(args) == 0:
|
case len(args) == 0:
|
||||||
|
@ -67,7 +73,7 @@ func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
|
||||||
return errors.Fatal("please specify a directory to restore to (--target)")
|
return errors.Fatal("please specify a directory to restore to (--target)")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(opts.Exclude) > 0 && len(opts.Include) > 0 {
|
if hasExcludes && hasIncludes {
|
||||||
return errors.Fatal("exclude and include patterns are mutually exclusive")
|
return errors.Fatal("exclude and include patterns are mutually exclusive")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,11 +131,16 @@ func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
|
||||||
Warnf("error for exclude pattern: %v", err)
|
Warnf("error for exclude pattern: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
matchedInsensitive, _, err := filter.InsensitiveList(opts.InsensitiveExclude, item)
|
||||||
|
if err != nil {
|
||||||
|
Warnf("error for iexclude pattern: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// An exclude filter is basically a 'wildcard but foo',
|
// An exclude filter is basically a 'wildcard but foo',
|
||||||
// so even if a childMayMatch, other children of a dir may not,
|
// so even if a childMayMatch, other children of a dir may not,
|
||||||
// therefore childMayMatch does not matter, but we should not go down
|
// therefore childMayMatch does not matter, but we should not go down
|
||||||
// unless the dir is selected for restore
|
// unless the dir is selected for restore
|
||||||
selectedForRestore = !matched
|
selectedForRestore = !matched && !matchedInsensitive
|
||||||
childMayBeSelected = selectedForRestore && node.Type == "dir"
|
childMayBeSelected = selectedForRestore && node.Type == "dir"
|
||||||
|
|
||||||
return selectedForRestore, childMayBeSelected
|
return selectedForRestore, childMayBeSelected
|
||||||
|
@ -141,15 +152,20 @@ func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
|
||||||
Warnf("error for include pattern: %v", err)
|
Warnf("error for include pattern: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedForRestore = matched
|
matchedInsensitive, childMayMatchInsensitive, err := filter.InsensitiveList(opts.InsensitiveInclude, item)
|
||||||
childMayBeSelected = childMayMatch && node.Type == "dir"
|
if err != nil {
|
||||||
|
Warnf("error for iexclude pattern: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedForRestore = matched || matchedInsensitive
|
||||||
|
childMayBeSelected = (childMayMatch || childMayMatchInsensitive) && node.Type == "dir"
|
||||||
|
|
||||||
return selectedForRestore, childMayBeSelected
|
return selectedForRestore, childMayBeSelected
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(opts.Exclude) > 0 {
|
if hasExcludes {
|
||||||
res.SelectFilter = selectExcludeFilter
|
res.SelectFilter = selectExcludeFilter
|
||||||
} else if len(opts.Include) > 0 {
|
} else if hasIncludes {
|
||||||
res.SelectFilter = selectIncludeFilter
|
res.SelectFilter = selectIncludeFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,3 +187,12 @@ func List(patterns []string, str string) (matched bool, childMayMatch bool, err
|
||||||
|
|
||||||
return matched, childMayMatch, nil
|
return matched, childMayMatch, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InsensitiveList is the same as List but case insensitive.
|
||||||
|
func InsensitiveList(patterns []string, str string) (matched bool, childMayMatch bool, err error) {
|
||||||
|
str = strings.ToLower(str)
|
||||||
|
for index, path := range patterns {
|
||||||
|
patterns[index] = strings.ToLower(path)
|
||||||
|
}
|
||||||
|
return List(patterns, str)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue