github.com/fawick/restic@v0.1.1-0.20171126184616-c02923fbfc79/cmd/restic/cmd_rebuild_index.go (about)

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