github.com/advanderveer/restic@v0.8.1-0.20171209104529-42a8c19aaea6/cmd/restic/cmd_rebuild_index.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/restic/restic/internal/errors"
     7  	"github.com/restic/restic/internal/index"
     8  	"github.com/restic/restic/internal/restic"
     9  
    10  	"github.com/spf13/cobra"
    11  )
    12  
    13  var cmdRebuildIndex = &cobra.Command{
    14  	Use:   "rebuild-index [flags]",
    15  	Short: "Build a new index file",
    16  	Long: `
    17  The "rebuild-index" command creates a new index based on the pack files in the
    18  repository.
    19  `,
    20  	DisableAutoGenTag: true,
    21  	RunE: func(cmd *cobra.Command, args []string) error {
    22  		return runRebuildIndex(globalOptions)
    23  	},
    24  }
    25  
    26  func init() {
    27  	cmdRoot.AddCommand(cmdRebuildIndex)
    28  }
    29  
    30  func runRebuildIndex(gopts GlobalOptions) error {
    31  	repo, err := OpenRepository(gopts)
    32  	if err != nil {
    33  		return err
    34  	}
    35  
    36  	lock, err := lockRepoExclusive(repo)
    37  	defer unlockRepo(lock)
    38  	if err != nil {
    39  		return err
    40  	}
    41  
    42  	ctx, cancel := context.WithCancel(gopts.ctx)
    43  	defer cancel()
    44  	return rebuildIndex(ctx, repo, restic.NewIDSet())
    45  }
    46  
    47  func rebuildIndex(ctx context.Context, repo restic.Repository, ignorePacks restic.IDSet) error {
    48  	Verbosef("counting files in repo\n")
    49  
    50  	var packs uint64
    51  	for range repo.List(ctx, restic.DataFile) {
    52  		packs++
    53  	}
    54  
    55  	bar := newProgressMax(!globalOptions.Quiet, packs-uint64(len(ignorePacks)), "packs")
    56  	idx, _, err := index.New(ctx, repo, ignorePacks, bar)
    57  	if err != nil {
    58  		return err
    59  	}
    60  
    61  	Verbosef("finding old index files\n")
    62  
    63  	var supersedes restic.IDs
    64  	for id := range repo.List(ctx, restic.IndexFile) {
    65  		supersedes = append(supersedes, id)
    66  	}
    67  
    68  	id, err := idx.Save(ctx, repo, supersedes)
    69  	if err != nil {
    70  		return errors.Fatalf("unable to save index, last error was: %v", err)
    71  	}
    72  
    73  	Verbosef("saved new index as %v\n", id.Str())
    74  
    75  	Verbosef("remove %d old index files\n", len(supersedes))
    76  
    77  	for _, id := range supersedes {
    78  		if err := repo.Backend().Remove(ctx, restic.Handle{
    79  			Type: restic.IndexFile,
    80  			Name: id.String(),
    81  		}); err != nil {
    82  			Warnf("error removing old index %v: %v\n", id.Str(), err)
    83  		}
    84  	}
    85  
    86  	return nil
    87  }