f4f8fae03d
When we use certain Git environment variables to find the Git directory and the working tree, we want those values to work regardless of what directory we're in. Currently we don't change the working directory, but we soon will in order to mimic Git's behavior. In order to make relative values of these environment variables work correctly once we change directories, let's turn them into absolute canonical paths when we set up the repository. We save the old environment variables into a variable and pass this variable to the helper for the git lfs env command, which wants to print the original values, not our modified ones. Note that we can't make the canonicalization conditional on the subcommand being run because the configuration structure has been initialized by the time we get to argument parsing and the configuration code invokes Git upon initialization. Because the Cygwin path canonicalization invokes a subprocess on Windows and the subprocess code caches the environment, we must also reset the cache after adjusting these environment variables so that future subprocess invocations, like those for Git, work as expected with the updated environment.
130 lines
4.2 KiB
Go
130 lines
4.2 KiB
Go
// Package lfs brings together the core LFS functionality
|
|
// NOTE: Subject to change, do not rely on this package from outside git-lfs source
|
|
package lfs
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/git-lfs/git-lfs/config"
|
|
"github.com/git-lfs/git-lfs/lfsapi"
|
|
"github.com/git-lfs/git-lfs/tools"
|
|
"github.com/git-lfs/git-lfs/tq"
|
|
"github.com/rubyist/tracerx"
|
|
)
|
|
|
|
func Environ(cfg *config.Configuration, manifest *tq.Manifest, envOverrides map[string]string) []string {
|
|
osEnviron := os.Environ()
|
|
env := make([]string, 0, len(osEnviron)+7)
|
|
|
|
api, err := lfsapi.NewClient(cfg)
|
|
if err != nil {
|
|
// TODO(@ttaylorr): don't panic
|
|
panic(err.Error())
|
|
}
|
|
|
|
if envOverrides == nil {
|
|
envOverrides = make(map[string]string, 0)
|
|
}
|
|
|
|
download := api.Endpoints.AccessFor(api.Endpoints.Endpoint("download", cfg.Remote()).Url)
|
|
upload := api.Endpoints.AccessFor(api.Endpoints.Endpoint("upload", cfg.PushRemote()).Url)
|
|
|
|
dltransfers := manifest.GetDownloadAdapterNames()
|
|
sort.Strings(dltransfers)
|
|
ultransfers := manifest.GetUploadAdapterNames()
|
|
sort.Strings(ultransfers)
|
|
|
|
fetchPruneConfig := NewFetchPruneConfig(cfg.Git)
|
|
|
|
references := strings.Join(cfg.LocalReferenceDirs(), ", ")
|
|
|
|
env = append(env,
|
|
fmt.Sprintf("LocalWorkingDir=%s", cfg.LocalWorkingDir()),
|
|
fmt.Sprintf("LocalGitDir=%s", cfg.LocalGitDir()),
|
|
fmt.Sprintf("LocalGitStorageDir=%s", cfg.LocalGitStorageDir()),
|
|
fmt.Sprintf("LocalMediaDir=%s", cfg.LFSObjectDir()),
|
|
fmt.Sprintf("LocalReferenceDirs=%s", references),
|
|
fmt.Sprintf("TempDir=%s", cfg.TempDir()),
|
|
fmt.Sprintf("ConcurrentTransfers=%d", api.ConcurrentTransfers()),
|
|
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),
|
|
fmt.Sprintf("LfsStorageDir=%s", cfg.LFSStorageDir()),
|
|
fmt.Sprintf("AccessDownload=%s", download.Mode()),
|
|
fmt.Sprintf("AccessUpload=%s", upload.Mode()),
|
|
fmt.Sprintf("DownloadTransfers=%s", strings.Join(dltransfers, ",")),
|
|
fmt.Sprintf("UploadTransfers=%s", strings.Join(ultransfers, ",")),
|
|
)
|
|
if len(cfg.FetchExcludePaths()) > 0 {
|
|
env = append(env, fmt.Sprintf("FetchExclude=%s", strings.Join(cfg.FetchExcludePaths(), ", ")))
|
|
}
|
|
if len(cfg.FetchIncludePaths()) > 0 {
|
|
env = append(env, fmt.Sprintf("FetchInclude=%s", strings.Join(cfg.FetchIncludePaths(), ", ")))
|
|
}
|
|
for _, ext := range cfg.Extensions() {
|
|
env = append(env, fmt.Sprintf("Extension[%d]=%s", ext.Priority, ext.Name))
|
|
}
|
|
|
|
for _, e := range osEnviron {
|
|
key := strings.SplitN(e, "=", 2)[0]
|
|
if !strings.HasPrefix(key, "GIT_") {
|
|
continue
|
|
}
|
|
if val, ok := envOverrides[key]; ok {
|
|
env = append(env, fmt.Sprintf("%s=%s", key, val))
|
|
} else {
|
|
env = append(env, e)
|
|
}
|
|
}
|
|
|
|
return env
|
|
}
|
|
|
|
func init() {
|
|
tracerx.DefaultKey = "GIT"
|
|
tracerx.Prefix = "trace git-lfs: "
|
|
if len(os.Getenv("GIT_TRACE")) < 1 {
|
|
if tt := os.Getenv("GIT_TRANSFER_TRACE"); len(tt) > 0 {
|
|
os.Setenv("GIT_TRACE", tt)
|
|
} else if cv := os.Getenv("GIT_CURL_VERBOSE"); len(cv) > 0 {
|
|
os.Setenv("GIT_TRACE", cv)
|
|
}
|
|
}
|
|
}
|
|
|
|
const (
|
|
gitExt = ".git"
|
|
gitPtrPrefix = "gitdir: "
|
|
)
|
|
|
|
func LinkOrCopyFromReference(cfg *config.Configuration, oid string, size int64) error {
|
|
if cfg.LFSObjectExists(oid, size) {
|
|
return nil
|
|
}
|
|
altMediafiles := cfg.Filesystem().ObjectReferencePaths(oid)
|
|
mediafile, err := cfg.Filesystem().ObjectPath(oid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, altMediafile := range altMediafiles {
|
|
tracerx.Printf("altMediafile: %s", altMediafile)
|
|
if altMediafile != "" && tools.FileExistsOfSize(altMediafile, size) {
|
|
err = LinkOrCopy(cfg, altMediafile, mediafile)
|
|
if err == nil {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return err
|
|
}
|