diff --git a/cmd/restic/cmd_backup.go b/cmd/restic/cmd_backup.go index c82ba8ff4..f612aa1ba 100644 --- a/cmd/restic/cmd_backup.go +++ b/cmd/restic/cmd_backup.go @@ -505,27 +505,20 @@ func collectTargets(opts BackupOptions, args []string) (targets []string, err er // parent returns the ID of the parent snapshot. If there is none, nil is // returned. func findParentSnapshot(ctx context.Context, repo restic.Repository, opts BackupOptions, targets []string, timeStampLimit time.Time) (parentID *restic.ID, err error) { - // Force using a parent - if !opts.Force && opts.Parent != "" { - id, err := restic.FindSnapshot(ctx, repo.Backend(), opts.Parent) - if err != nil { - return nil, errors.Fatalf("invalid id %q: %v", opts.Parent, err) - } - - parentID = &id + if opts.Force { + return nil, nil } - // Find last snapshot to set it as parent, if not already set - if !opts.Force && parentID == nil { - id, err := restic.FindLatestSnapshot(ctx, repo.Backend(), repo, targets, []restic.TagList{}, []string{opts.Host}, &timeStampLimit) - if err == nil { - parentID = &id - } else if err != restic.ErrNoSnapshotFound { - return nil, err - } + snName := opts.Parent + if snName == "" { + snName = "latest" } - - return parentID, nil + id, err := restic.FindFilteredSnapshot(ctx, repo.Backend(), repo, []string{opts.Host}, []restic.TagList{}, targets, &timeStampLimit, snName) + // Snapshot not found is ok if no explicit parent was set + if opts.Parent == "" && errors.Is(err, restic.ErrNoSnapshotFound) { + err = nil + } + return &id, err } func runBackup(ctx context.Context, opts BackupOptions, gopts GlobalOptions, term *termstatus.Terminal, args []string) error { diff --git a/cmd/restic/cmd_dump.go b/cmd/restic/cmd_dump.go index 4f2827b02..6fe531fff 100644 --- a/cmd/restic/cmd_dump.go +++ b/cmd/restic/cmd_dump.go @@ -139,7 +139,7 @@ func runDump(ctx context.Context, opts DumpOptions, gopts GlobalOptions, args [] } } - id, err := restic.FindFilteredSnapshot(ctx, repo.Backend(), repo, opts.Paths, opts.Tags, opts.Hosts, snapshotIDString) + id, err := restic.FindFilteredSnapshot(ctx, repo.Backend(), repo, opts.Paths, opts.Tags, opts.Hosts, nil, snapshotIDString) if err != nil { Exitf(1, "failed to find snapshot: %v", err) } diff --git a/cmd/restic/cmd_ls.go b/cmd/restic/cmd_ls.go index 5b8c845d1..1cb2cfa66 100644 --- a/cmd/restic/cmd_ls.go +++ b/cmd/restic/cmd_ls.go @@ -210,7 +210,7 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri } } - id, err := restic.FindFilteredSnapshot(ctx, snapshotLister, repo, opts.Hosts, opts.Tags, opts.Paths, args[0]) + id, err := restic.FindFilteredSnapshot(ctx, snapshotLister, repo, opts.Hosts, opts.Tags, opts.Paths, nil, args[0]) if err != nil { return err } diff --git a/cmd/restic/cmd_restore.go b/cmd/restic/cmd_restore.go index 33a12b441..b58ccc061 100644 --- a/cmd/restic/cmd_restore.go +++ b/cmd/restic/cmd_restore.go @@ -131,7 +131,7 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions, a } } - id, err := restic.FindFilteredSnapshot(ctx, repo.Backend(), repo, opts.Hosts, opts.Tags, opts.Paths, snapshotIDString) + id, err := restic.FindFilteredSnapshot(ctx, repo.Backend(), repo, opts.Hosts, opts.Tags, opts.Paths, nil, snapshotIDString) if err != nil { Exitf(1, "failed to find snapshot %q: %v", snapshotIDString, err) } diff --git a/internal/restic/snapshot_find.go b/internal/restic/snapshot_find.go index 088b920ec..6c94dbe29 100644 --- a/internal/restic/snapshot_find.go +++ b/internal/restic/snapshot_find.go @@ -2,6 +2,7 @@ package restic import ( "context" + "fmt" "path/filepath" "time" @@ -88,11 +89,11 @@ func FindSnapshot(ctx context.Context, be Lister, s string) (ID, error) { return ParseID(name) } -func FindFilteredSnapshot(ctx context.Context, be Lister, loader LoaderUnpacked, hosts []string, tags []TagList, paths []string, snapshotID string) (ID, error) { +func FindFilteredSnapshot(ctx context.Context, be Lister, loader LoaderUnpacked, hosts []string, tags []TagList, paths []string, timeStampLimit *time.Time, snapshotID string) (ID, error) { if snapshotID == "latest" { - id, err := FindLatestSnapshot(ctx, be, loader, paths, tags, hosts, nil) + id, err := FindLatestSnapshot(ctx, be, loader, paths, tags, hosts, timeStampLimit) if err == ErrNoSnapshotFound { - err = errors.Errorf("no snapshot matched given filter (Paths:%v Tags:%v Hosts:%v)", paths, tags, hosts) + err = fmt.Errorf("snapshot filter (Paths:%v Tags:%v Hosts:%v): %w", paths, tags, hosts, err) } return id, err } else {