github.com/psexton/git-lfs@v2.1.1-0.20170517224304-289a18b2bc53+incompatible/lfs/lfs.go (about)

     1  // Package lfs brings together the core LFS functionality
     2  // NOTE: Subject to change, do not rely on this package from outside git-lfs source
     3  package lfs
     4  
     5  import (
     6  	"fmt"
     7  	"os"
     8  	"path/filepath"
     9  	"sort"
    10  	"strings"
    11  
    12  	"github.com/git-lfs/git-lfs/config"
    13  	"github.com/git-lfs/git-lfs/lfsapi"
    14  	"github.com/git-lfs/git-lfs/localstorage"
    15  	"github.com/git-lfs/git-lfs/tools"
    16  	"github.com/git-lfs/git-lfs/tq"
    17  	"github.com/rubyist/tracerx"
    18  )
    19  
    20  var (
    21  	LargeSizeThreshold = 5 * 1024 * 1024
    22  )
    23  
    24  // LocalMediaDir returns the root of lfs objects
    25  func LocalMediaDir() string {
    26  	if localstorage.Objects() != nil {
    27  		return localstorage.Objects().RootDir
    28  	}
    29  	return ""
    30  }
    31  
    32  func LocalObjectTempDir() string {
    33  	if localstorage.Objects() != nil {
    34  		return localstorage.Objects().TempDir
    35  	}
    36  	return ""
    37  }
    38  
    39  func TempDir() string {
    40  	return localstorage.TempDir
    41  }
    42  
    43  func TempFile(prefix string) (*os.File, error) {
    44  	return localstorage.TempFile(prefix)
    45  }
    46  
    47  func LocalMediaPath(oid string) (string, error) {
    48  	return localstorage.Objects().BuildObjectPath(oid)
    49  }
    50  
    51  func LocalMediaPathReadOnly(oid string) string {
    52  	return localstorage.Objects().ObjectPath(oid)
    53  }
    54  
    55  func LocalReferencePath(sha string) string {
    56  	if config.LocalReferenceDir == "" {
    57  		return ""
    58  	}
    59  	return filepath.Join(config.LocalReferenceDir, sha[0:2], sha[2:4], sha)
    60  }
    61  
    62  func ObjectExistsOfSize(oid string, size int64) bool {
    63  	path := localstorage.Objects().ObjectPath(oid)
    64  	return tools.FileExistsOfSize(path, size)
    65  }
    66  
    67  func Environ(cfg *config.Configuration, manifest *tq.Manifest) []string {
    68  	osEnviron := os.Environ()
    69  	env := make([]string, 0, len(osEnviron)+7)
    70  
    71  	api, err := lfsapi.NewClient(cfg.Os, cfg.Git)
    72  	if err != nil {
    73  		// TODO(@ttaylorr): don't panic
    74  		panic(err.Error())
    75  	}
    76  
    77  	download := api.Endpoints.AccessFor(api.Endpoints.Endpoint("download", cfg.CurrentRemote).Url)
    78  	upload := api.Endpoints.AccessFor(api.Endpoints.Endpoint("upload", cfg.CurrentRemote).Url)
    79  
    80  	dltransfers := manifest.GetDownloadAdapterNames()
    81  	sort.Strings(dltransfers)
    82  	ultransfers := manifest.GetUploadAdapterNames()
    83  	sort.Strings(ultransfers)
    84  
    85  	fetchPruneConfig := cfg.FetchPruneConfig()
    86  
    87  	env = append(env,
    88  		fmt.Sprintf("LocalWorkingDir=%s", config.LocalWorkingDir),
    89  		fmt.Sprintf("LocalGitDir=%s", config.LocalGitDir),
    90  		fmt.Sprintf("LocalGitStorageDir=%s", config.LocalGitStorageDir),
    91  		fmt.Sprintf("LocalMediaDir=%s", LocalMediaDir()),
    92  		fmt.Sprintf("LocalReferenceDir=%s", config.LocalReferenceDir),
    93  		fmt.Sprintf("TempDir=%s", TempDir()),
    94  		fmt.Sprintf("ConcurrentTransfers=%d", api.ConcurrentTransfers),
    95  		fmt.Sprintf("TusTransfers=%v", cfg.TusTransfersAllowed()),
    96  		fmt.Sprintf("BasicTransfersOnly=%v", cfg.BasicTransfersOnly()),
    97  		fmt.Sprintf("SkipDownloadErrors=%v", cfg.SkipDownloadErrors()),
    98  		fmt.Sprintf("FetchRecentAlways=%v", fetchPruneConfig.FetchRecentAlways),
    99  		fmt.Sprintf("FetchRecentRefsDays=%d", fetchPruneConfig.FetchRecentRefsDays),
   100  		fmt.Sprintf("FetchRecentCommitsDays=%d", fetchPruneConfig.FetchRecentCommitsDays),
   101  		fmt.Sprintf("FetchRecentRefsIncludeRemotes=%v", fetchPruneConfig.FetchRecentRefsIncludeRemotes),
   102  		fmt.Sprintf("PruneOffsetDays=%d", fetchPruneConfig.PruneOffsetDays),
   103  		fmt.Sprintf("PruneVerifyRemoteAlways=%v", fetchPruneConfig.PruneVerifyRemoteAlways),
   104  		fmt.Sprintf("PruneRemoteName=%s", fetchPruneConfig.PruneRemoteName),
   105  		fmt.Sprintf("AccessDownload=%s", download),
   106  		fmt.Sprintf("AccessUpload=%s", upload),
   107  		fmt.Sprintf("DownloadTransfers=%s", strings.Join(dltransfers, ",")),
   108  		fmt.Sprintf("UploadTransfers=%s", strings.Join(ultransfers, ",")),
   109  	)
   110  	if len(cfg.FetchExcludePaths()) > 0 {
   111  		env = append(env, fmt.Sprintf("FetchExclude=%s", strings.Join(cfg.FetchExcludePaths(), ", ")))
   112  	}
   113  	if len(cfg.FetchIncludePaths()) > 0 {
   114  		env = append(env, fmt.Sprintf("FetchInclude=%s", strings.Join(cfg.FetchIncludePaths(), ", ")))
   115  	}
   116  	for _, ext := range cfg.Extensions() {
   117  		env = append(env, fmt.Sprintf("Extension[%d]=%s", ext.Priority, ext.Name))
   118  	}
   119  
   120  	for _, e := range osEnviron {
   121  		if !strings.Contains(strings.SplitN(e, "=", 2)[0], "GIT_") {
   122  			continue
   123  		}
   124  		env = append(env, e)
   125  	}
   126  
   127  	return env
   128  }
   129  
   130  func InRepo() bool {
   131  	return config.LocalGitDir != ""
   132  }
   133  
   134  func ClearTempObjects() error {
   135  	if localstorage.Objects() == nil {
   136  		return nil
   137  	}
   138  	return localstorage.Objects().ClearTempObjects()
   139  }
   140  
   141  func ScanObjectsChan() <-chan localstorage.Object {
   142  	return localstorage.Objects().ScanObjectsChan()
   143  }
   144  
   145  func init() {
   146  	tracerx.DefaultKey = "GIT"
   147  	tracerx.Prefix = "trace git-lfs: "
   148  	if len(os.Getenv("GIT_TRACE")) < 1 {
   149  		if tt := os.Getenv("GIT_TRANSFER_TRACE"); len(tt) > 0 {
   150  			os.Setenv("GIT_TRACE", tt)
   151  		}
   152  	}
   153  }
   154  
   155  const (
   156  	gitExt       = ".git"
   157  	gitPtrPrefix = "gitdir: "
   158  )
   159  
   160  // only used in tests
   161  func AllObjects() []localstorage.Object {
   162  	return localstorage.Objects().AllObjects()
   163  }
   164  
   165  func LinkOrCopyFromReference(oid string, size int64) error {
   166  	if ObjectExistsOfSize(oid, size) {
   167  		return nil
   168  	}
   169  	altMediafile := LocalReferencePath(oid)
   170  	mediafile, err := LocalMediaPath(oid)
   171  	if err != nil {
   172  		return err
   173  	}
   174  	if altMediafile != "" && tools.FileExistsOfSize(altMediafile, size) {
   175  		return LinkOrCopy(altMediafile, mediafile)
   176  	}
   177  	return nil
   178  }