github.com/stffabi/git-lfs@v2.3.5-0.20180214015214-8eeaa8d88902+incompatible/commands/command_checkout.go (about)

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  
     7  	"github.com/git-lfs/git-lfs/filepathfilter"
     8  	"github.com/git-lfs/git-lfs/git"
     9  	"github.com/git-lfs/git-lfs/lfs"
    10  	"github.com/git-lfs/git-lfs/tasklog"
    11  	"github.com/git-lfs/git-lfs/tq"
    12  	"github.com/spf13/cobra"
    13  )
    14  
    15  func checkoutCommand(cmd *cobra.Command, args []string) {
    16  	requireInRepo()
    17  	ref, err := git.CurrentRef()
    18  	if err != nil {
    19  		Panic(err, "Could not checkout")
    20  	}
    21  
    22  	singleCheckout := newSingleCheckout(cfg.Git, "")
    23  	if singleCheckout.Skip() {
    24  		fmt.Println("Cannot checkout LFS objects, Git LFS is not installed.")
    25  		return
    26  	}
    27  
    28  	var totalBytes int64
    29  	var pointers []*lfs.WrappedPointer
    30  	logger := tasklog.NewLogger(os.Stdout)
    31  	meter := tq.NewMeter()
    32  	meter.Logger = meter.LoggerFromEnv(cfg.Os)
    33  	logger.Enqueue(meter)
    34  	chgitscanner := lfs.NewGitScanner(func(p *lfs.WrappedPointer, err error) {
    35  		if err != nil {
    36  			LoggedError(err, "Scanner error: %s", err)
    37  			return
    38  		}
    39  
    40  		totalBytes += p.Size
    41  		meter.Add(p.Size)
    42  		meter.StartTransfer(p.Name)
    43  		pointers = append(pointers, p)
    44  	})
    45  
    46  	chgitscanner.Filter = filepathfilter.New(rootedPaths(args), nil)
    47  
    48  	if err := chgitscanner.ScanTree(ref.Sha); err != nil {
    49  		ExitWithError(err)
    50  	}
    51  	chgitscanner.Close()
    52  
    53  	meter.Start()
    54  	for _, p := range pointers {
    55  		singleCheckout.Run(p)
    56  
    57  		// not strictly correct (parallel) but we don't have a callback & it's just local
    58  		// plus only 1 slot in channel so it'll block & be close
    59  		meter.TransferBytes("checkout", p.Name, p.Size, totalBytes, int(p.Size))
    60  		meter.FinishTransfer(p.Name)
    61  	}
    62  
    63  	meter.Finish()
    64  	singleCheckout.Close()
    65  }
    66  
    67  // Parameters are filters
    68  // firstly convert any pathspecs to the root of the repo, in case this is being
    69  // executed in a sub-folder
    70  func rootedPaths(args []string) []string {
    71  	pathConverter, err := lfs.NewCurrentToRepoPathConverter(cfg)
    72  	if err != nil {
    73  		Panic(err, "Could not checkout")
    74  	}
    75  
    76  	rootedpaths := make([]string, 0, len(args))
    77  	for _, arg := range args {
    78  		rootedpaths = append(rootedpaths, pathConverter.Convert(arg))
    79  	}
    80  	return rootedpaths
    81  }
    82  
    83  func init() {
    84  	RegisterCommand("checkout", checkoutCommand, nil)
    85  }