2016-05-18 10:43:42 +00:00
|
|
|
// Package lfs brings together the core LFS functionality
|
|
|
|
// NOTE: Subject to change, do not rely on this package from outside git-lfs source
|
2015-03-19 19:30:55 +00:00
|
|
|
package lfs
|
2013-09-22 23:04:06 +00:00
|
|
|
|
2013-09-27 14:39:58 +00:00
|
|
|
import (
|
2014-01-24 01:30:48 +00:00
|
|
|
"fmt"
|
2013-09-27 15:19:54 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2016-07-27 13:42:00 +00:00
|
|
|
"sort"
|
2013-09-27 14:39:58 +00:00
|
|
|
"strings"
|
2015-05-13 19:43:41 +00:00
|
|
|
|
2016-11-15 17:01:18 +00:00
|
|
|
"github.com/git-lfs/git-lfs/config"
|
2017-04-14 16:30:45 +00:00
|
|
|
"github.com/git-lfs/git-lfs/lfsapi"
|
2016-11-15 17:01:18 +00:00
|
|
|
"github.com/git-lfs/git-lfs/localstorage"
|
|
|
|
"github.com/git-lfs/git-lfs/tools"
|
2016-12-12 00:28:47 +00:00
|
|
|
"github.com/git-lfs/git-lfs/tq"
|
2016-05-23 18:02:27 +00:00
|
|
|
"github.com/rubyist/tracerx"
|
2013-09-27 14:39:58 +00:00
|
|
|
)
|
|
|
|
|
2013-09-27 15:19:54 +00:00
|
|
|
var (
|
|
|
|
LargeSizeThreshold = 5 * 1024 * 1024
|
|
|
|
)
|
|
|
|
|
2016-05-17 09:28:42 +00:00
|
|
|
// LocalMediaDir returns the root of lfs objects
|
|
|
|
func LocalMediaDir() string {
|
|
|
|
if localstorage.Objects() != nil {
|
|
|
|
return localstorage.Objects().RootDir
|
2016-05-13 16:38:06 +00:00
|
|
|
}
|
2016-05-17 09:28:42 +00:00
|
|
|
return ""
|
2016-05-13 16:38:06 +00:00
|
|
|
}
|
|
|
|
|
2016-05-17 09:28:42 +00:00
|
|
|
func LocalObjectTempDir() string {
|
|
|
|
if localstorage.Objects() != nil {
|
|
|
|
return localstorage.Objects().TempDir
|
2014-08-05 15:44:34 +00:00
|
|
|
}
|
2016-05-17 09:28:42 +00:00
|
|
|
return ""
|
|
|
|
}
|
2014-08-05 15:44:34 +00:00
|
|
|
|
2016-05-17 09:28:42 +00:00
|
|
|
func TempDir() string {
|
|
|
|
return localstorage.TempDir
|
2013-09-27 15:19:54 +00:00
|
|
|
}
|
2013-09-27 14:39:58 +00:00
|
|
|
|
2016-05-17 09:28:42 +00:00
|
|
|
func TempFile(prefix string) (*os.File, error) {
|
|
|
|
return localstorage.TempFile(prefix)
|
2014-08-05 16:06:22 +00:00
|
|
|
}
|
|
|
|
|
2015-11-24 20:03:43 +00:00
|
|
|
func LocalMediaPath(oid string) (string, error) {
|
2016-05-17 09:28:42 +00:00
|
|
|
return localstorage.Objects().BuildObjectPath(oid)
|
2013-09-27 15:19:54 +00:00
|
|
|
}
|
|
|
|
|
2016-05-13 16:38:06 +00:00
|
|
|
func LocalMediaPathReadOnly(oid string) string {
|
2016-05-17 09:28:42 +00:00
|
|
|
return localstorage.Objects().ObjectPath(oid)
|
2016-05-13 16:38:06 +00:00
|
|
|
}
|
|
|
|
|
2016-01-31 21:06:40 +00:00
|
|
|
func LocalReferencePath(sha string) string {
|
2016-05-13 16:38:06 +00:00
|
|
|
if config.LocalReferenceDir == "" {
|
2016-01-31 21:06:40 +00:00
|
|
|
return ""
|
|
|
|
}
|
2016-05-13 16:38:06 +00:00
|
|
|
return filepath.Join(config.LocalReferenceDir, sha[0:2], sha[2:4], sha)
|
2016-01-31 21:06:40 +00:00
|
|
|
}
|
|
|
|
|
2015-11-24 20:03:43 +00:00
|
|
|
func ObjectExistsOfSize(oid string, size int64) bool {
|
2016-05-17 09:28:42 +00:00
|
|
|
path := localstorage.Objects().ObjectPath(oid)
|
2016-05-13 16:38:06 +00:00
|
|
|
return tools.FileExistsOfSize(path, size)
|
2015-07-24 16:27:39 +00:00
|
|
|
}
|
|
|
|
|
2016-12-12 00:28:47 +00:00
|
|
|
func Environ(cfg *config.Configuration, manifest *tq.Manifest) []string {
|
2014-01-24 01:30:48 +00:00
|
|
|
osEnviron := os.Environ()
|
2015-07-31 11:48:08 +00:00
|
|
|
env := make([]string, 0, len(osEnviron)+7)
|
2016-08-10 15:37:58 +00:00
|
|
|
|
2017-04-14 16:30:45 +00:00
|
|
|
api, err := lfsapi.NewClient(cfg.Os, cfg.Git)
|
|
|
|
if err != nil {
|
|
|
|
// TODO(@ttaylorr): don't panic
|
|
|
|
panic(err.Error())
|
|
|
|
}
|
|
|
|
|
2017-04-14 16:39:36 +00:00
|
|
|
download := api.Endpoints.AccessFor(api.Endpoints.Endpoint("download", cfg.CurrentRemote).Url)
|
|
|
|
upload := api.Endpoints.AccessFor(api.Endpoints.Endpoint("upload", cfg.CurrentRemote).Url)
|
|
|
|
|
2016-08-09 22:07:41 +00:00
|
|
|
dltransfers := manifest.GetDownloadAdapterNames()
|
2016-07-27 13:42:00 +00:00
|
|
|
sort.Strings(dltransfers)
|
2016-08-09 22:07:41 +00:00
|
|
|
ultransfers := manifest.GetUploadAdapterNames()
|
2016-07-27 13:42:00 +00:00
|
|
|
sort.Strings(ultransfers)
|
|
|
|
|
2016-08-10 15:37:58 +00:00
|
|
|
fetchPruneConfig := cfg.FetchPruneConfig()
|
|
|
|
|
2015-07-31 11:17:50 +00:00
|
|
|
env = append(env,
|
2016-05-13 16:38:06 +00:00
|
|
|
fmt.Sprintf("LocalWorkingDir=%s", config.LocalWorkingDir),
|
|
|
|
fmt.Sprintf("LocalGitDir=%s", config.LocalGitDir),
|
|
|
|
fmt.Sprintf("LocalGitStorageDir=%s", config.LocalGitStorageDir),
|
2016-05-17 09:28:42 +00:00
|
|
|
fmt.Sprintf("LocalMediaDir=%s", LocalMediaDir()),
|
2016-05-13 16:38:06 +00:00
|
|
|
fmt.Sprintf("LocalReferenceDir=%s", config.LocalReferenceDir),
|
2016-05-17 09:28:42 +00:00
|
|
|
fmt.Sprintf("TempDir=%s", TempDir()),
|
2017-04-14 16:30:45 +00:00
|
|
|
fmt.Sprintf("ConcurrentTransfers=%d", api.ConcurrentTransfers),
|
2016-08-10 15:37:58 +00:00
|
|
|
fmt.Sprintf("TusTransfers=%v", cfg.TusTransfersAllowed()),
|
|
|
|
fmt.Sprintf("BasicTransfersOnly=%v", cfg.BasicTransfersOnly()),
|
|
|
|
fmt.Sprintf("SkipDownloadErrors=%v", cfg.SkipDownloadErrors()),
|
|
|
|
fmt.Sprintf("FetchRecentAlways=%v", fetchPruneConfig.FetchRecentAlways),
|
|
|
|
fmt.Sprintf("FetchRecentRefsDays=%d", fetchPruneConfig.FetchRecentRefsDays),
|
|
|
|
fmt.Sprintf("FetchRecentCommitsDays=%d", fetchPruneConfig.FetchRecentCommitsDays),
|
|
|
|
fmt.Sprintf("FetchRecentRefsIncludeRemotes=%v", fetchPruneConfig.FetchRecentRefsIncludeRemotes),
|
|
|
|
fmt.Sprintf("PruneOffsetDays=%d", fetchPruneConfig.PruneOffsetDays),
|
|
|
|
fmt.Sprintf("PruneVerifyRemoteAlways=%v", fetchPruneConfig.PruneVerifyRemoteAlways),
|
|
|
|
fmt.Sprintf("PruneRemoteName=%s", fetchPruneConfig.PruneRemoteName),
|
2017-04-14 16:39:36 +00:00
|
|
|
fmt.Sprintf("AccessDownload=%s", download),
|
|
|
|
fmt.Sprintf("AccessUpload=%s", upload),
|
2016-07-27 13:42:00 +00:00
|
|
|
fmt.Sprintf("DownloadTransfers=%s", strings.Join(dltransfers, ",")),
|
|
|
|
fmt.Sprintf("UploadTransfers=%s", strings.Join(ultransfers, ",")),
|
2015-07-31 11:17:50 +00:00
|
|
|
)
|
2016-08-10 15:37:58 +00:00
|
|
|
if len(cfg.FetchExcludePaths()) > 0 {
|
|
|
|
env = append(env, fmt.Sprintf("FetchExclude=%s", strings.Join(cfg.FetchExcludePaths(), ", ")))
|
2016-05-13 16:38:06 +00:00
|
|
|
}
|
2016-08-10 15:37:58 +00:00
|
|
|
if len(cfg.FetchIncludePaths()) > 0 {
|
|
|
|
env = append(env, fmt.Sprintf("FetchInclude=%s", strings.Join(cfg.FetchIncludePaths(), ", ")))
|
2016-05-13 16:38:06 +00:00
|
|
|
}
|
2016-08-10 15:37:58 +00:00
|
|
|
for _, ext := range cfg.Extensions() {
|
2016-05-13 16:38:06 +00:00
|
|
|
env = append(env, fmt.Sprintf("Extension[%d]=%s", ext.Priority, ext.Name))
|
|
|
|
}
|
2014-01-24 01:30:48 +00:00
|
|
|
|
2014-05-22 22:38:36 +00:00
|
|
|
for _, e := range osEnviron {
|
2017-01-04 20:27:05 +00:00
|
|
|
if !strings.Contains(strings.SplitN(e, "=", 2)[0], "GIT_") {
|
2014-01-24 01:30:48 +00:00
|
|
|
continue
|
|
|
|
}
|
2014-02-01 20:11:33 +00:00
|
|
|
env = append(env, e)
|
2014-01-24 01:30:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return env
|
|
|
|
}
|
|
|
|
|
2014-06-03 21:05:58 +00:00
|
|
|
func InRepo() bool {
|
2016-05-13 16:38:06 +00:00
|
|
|
return config.LocalGitDir != ""
|
2015-09-09 14:17:16 +00:00
|
|
|
}
|
|
|
|
|
2016-02-23 18:20:28 +00:00
|
|
|
func ClearTempObjects() error {
|
2016-05-17 09:28:42 +00:00
|
|
|
if localstorage.Objects() == nil {
|
2016-02-23 18:20:28 +00:00
|
|
|
return nil
|
|
|
|
}
|
2016-05-17 09:28:42 +00:00
|
|
|
return localstorage.Objects().ClearTempObjects()
|
2016-02-23 18:20:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func ScanObjectsChan() <-chan localstorage.Object {
|
2016-05-17 09:28:42 +00:00
|
|
|
return localstorage.Objects().ScanObjectsChan()
|
2016-02-23 18:20:28 +00:00
|
|
|
}
|
|
|
|
|
2015-09-09 14:17:16 +00:00
|
|
|
func init() {
|
|
|
|
tracerx.DefaultKey = "GIT"
|
|
|
|
tracerx.Prefix = "trace git-lfs: "
|
2017-03-23 16:29:31 +00:00
|
|
|
if len(os.Getenv("GIT_TRACE")) < 1 {
|
|
|
|
if tt := os.Getenv("GIT_TRANSFER_TRACE"); len(tt) > 0 {
|
|
|
|
os.Setenv("GIT_TRACE", tt)
|
|
|
|
}
|
|
|
|
}
|
2014-06-11 18:29:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const (
|
|
|
|
gitExt = ".git"
|
|
|
|
gitPtrPrefix = "gitdir: "
|
|
|
|
)
|
2015-09-09 14:14:37 +00:00
|
|
|
|
2016-02-23 18:14:43 +00:00
|
|
|
// only used in tests
|
|
|
|
func AllObjects() []localstorage.Object {
|
2016-05-17 09:28:42 +00:00
|
|
|
return localstorage.Objects().AllObjects()
|
2016-02-23 18:14:43 +00:00
|
|
|
}
|
2016-03-01 19:51:34 +00:00
|
|
|
|
2016-04-04 21:09:07 +00:00
|
|
|
func LinkOrCopyFromReference(oid string, size int64) error {
|
|
|
|
if ObjectExistsOfSize(oid, size) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
altMediafile := LocalReferencePath(oid)
|
|
|
|
mediafile, err := LocalMediaPath(oid)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-05-13 16:38:06 +00:00
|
|
|
if altMediafile != "" && tools.FileExistsOfSize(altMediafile, size) {
|
2016-04-04 21:09:07 +00:00
|
|
|
return LinkOrCopy(altMediafile, mediafile)
|
2016-03-01 19:51:34 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|