Merge pull request #817 from restic/add-forget-prune

Add `--prune` switch to `forget`
This commit is contained in:
Alexander Neumann 2017-02-21 11:40:30 +01:00
commit 3d1dc636d0
3 changed files with 55 additions and 3 deletions

View file

@ -545,7 +545,8 @@ be done either manually (by specifying a snapshot ID to remove) or by using a
policy that describes which snapshots to forget. For all remove operations, two
commands need to be called in sequence: `forget` to remove a snapshot and
`prune` to actually remove the data that was referenced by the snapshot from
the repository.
the repository. This can be automated with the `--prune` option of the `forget`
command, which runs `prune` automatically if snapshots have been removed.
## Remove a single snapshot
@ -610,6 +611,41 @@ done
Afterwards the repository is smaller.
You can automate this two-step process by using the `--prune` switch to
`forget`:
```console
$ restic forget --keep-last 1 --prune
snapshots for host mopped, directories /home/user/work:
keep 1 snapshots:
ID Date Host Tags Directory
----------------------------------------------------------------------
4bba301e 2017-02-21 10:49:18 mopped /home/user/work
remove 1 snapshots:
ID Date Host Tags Directory
----------------------------------------------------------------------
8c02b94b 2017-02-21 10:48:33 mopped /home/user/work
1 snapshots have been removed, running prune
counting files in repo
building new index for repo
[0:00] 100.00% 37 / 37 packs
repository contains 37 packs (5521 blobs) with 151.012 MiB bytes
processed 5521 blobs: 0 duplicate blobs, 0B duplicate
load all snapshots
find data that is still in use for 1 snapshots
[0:00] 100.00% 1 / 1 snapshots
found 5323 of 5521 data blobs still in use, removing 198 blobs
will delete 0 packs and rewrite 27 packs, this frees 22.106 MiB
creating new index
[0:00] 100.00% 30 / 30 packs
saved new index as b49f3e68
done
```
## Removing snapshots according to a policy
Removing snapshots manually is tedious and error-prone, therefore restic allows
@ -747,4 +783,4 @@ enter password for repository:
Restic supports the output of some commands in JSON format. The JSON flag ```--json``` is currently supported only by ```restic snapshots```.
```console
$ restic -r /tmp/backup snapshots --json```
$ restic -r /tmp/backup snapshots --json```

View file

@ -38,6 +38,7 @@ type ForgetOptions struct {
Tags []string
DryRun bool
Prune bool
}
var forgetOptions ForgetOptions
@ -58,6 +59,7 @@ func init() {
f.StringSliceVar(&forgetOptions.Tags, "tag", []string{}, "only forget snapshots with the `tag` (can be specified multiple times)")
f.BoolVarP(&forgetOptions.DryRun, "dry-run", "n", false, "do not delete anything, just print what would be done")
f.BoolVar(&forgetOptions.Prune, "prune", false, "automatically run the 'prune' command if snapshots have been removed")
}
func printSnapshots(w io.Writer, snapshots restic.Snapshots) {
@ -188,6 +190,7 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
snapshotGroups[k] = list
}
removeSnapshots := 0
for key, snapshotGroup := range snapshotGroups {
Printf("snapshots for host %v, directories %v:\n\n", key.Hostname, key.Dirs)
keep, remove := restic.ApplyPolicy(snapshotGroup, policy)
@ -200,6 +203,8 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
printSnapshots(globalOptions.stdout, remove)
Printf("\n")
removeSnapshots += len(remove)
if !opts.DryRun {
for _, sn := range remove {
h := restic.Handle{Type: restic.SnapshotFile, Name: sn.ID().String()}
@ -211,5 +216,12 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
}
}
if removeSnapshots > 0 && opts.Prune {
Printf("%d snapshots have been removed, running prune\n", removeSnapshots)
if !opts.DryRun {
return pruneRepository(gopts, repo)
}
}
return nil
}

View file

@ -75,7 +75,11 @@ func runPrune(gopts GlobalOptions) error {
return err
}
err = repo.LoadIndex()
return pruneRepository(gopts, repo)
}
func pruneRepository(gopts GlobalOptions, repo restic.Repository) error {
err := repo.LoadIndex()
if err != nil {
return err
}