Merge branch 'master' into allow-skippable-auth
This commit is contained in:
commit
b71f0ef8bd
@ -149,8 +149,8 @@ type Committer struct {
|
|||||||
// "user.name" and "user.email" configuration values are used from the
|
// "user.name" and "user.email" configuration values are used from the
|
||||||
// config.Config singleton.
|
// config.Config singleton.
|
||||||
func CurrentCommitter() Committer {
|
func CurrentCommitter() Committer {
|
||||||
name, _ := config.Config.GitConfig("user.name")
|
name, _ := config.Config.Git.Get("user.name")
|
||||||
email, _ := config.Config.GitConfig("user.email")
|
email, _ := config.Config.Git.Get("user.email")
|
||||||
|
|
||||||
return Committer{name, email}
|
return Committer{name, email}
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ func execCredsCommand(cfg *config.Configuration, input Creds, subCommand string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := err.(*exec.ExitError); ok {
|
if _, ok := err.(*exec.ExitError); ok {
|
||||||
if !cfg.GetenvBool("GIT_TERMINAL_PROMPT", true) {
|
if !cfg.Os.Bool("GIT_TERMINAL_PROMPT", true) {
|
||||||
return nil, fmt.Errorf("Change the GIT_TERMINAL_PROMPT env var to be prompted to enter your credentials for %s://%s.",
|
return nil, fmt.Errorf("Change the GIT_TERMINAL_PROMPT env var to be prompted to enter your credentials for %s://%s.",
|
||||||
input["protocol"], input["host"])
|
input["protocol"], input["host"])
|
||||||
}
|
}
|
||||||
|
@ -69,8 +69,9 @@ func sshGetExeAndArgs(cfg *config.Configuration, endpoint config.Endpoint) (exe
|
|||||||
isPlink := false
|
isPlink := false
|
||||||
isTortoise := false
|
isTortoise := false
|
||||||
|
|
||||||
ssh := cfg.Getenv("GIT_SSH")
|
ssh, _ := cfg.Os.Get("GIT_SSH")
|
||||||
cmdArgs := strings.Fields(cfg.Getenv("GIT_SSH_COMMAND"))
|
sshCmd, _ := cfg.Os.Get("GIT_SSH_COMMAND")
|
||||||
|
cmdArgs := strings.Fields(sshCmd)
|
||||||
if len(cmdArgs) > 0 {
|
if len(cmdArgs) > 0 {
|
||||||
ssh = cmdArgs[0]
|
ssh = cmdArgs[0]
|
||||||
cmdArgs = cmdArgs[1:]
|
cmdArgs = cmdArgs[1:]
|
||||||
|
@ -108,7 +108,9 @@ func checkoutWithIncludeExclude(include []string, exclude []string) {
|
|||||||
for _, pointer := range pointers {
|
for _, pointer := range pointers {
|
||||||
totalBytes += pointer.Size
|
totalBytes += pointer.Size
|
||||||
}
|
}
|
||||||
progress := progress.NewProgressMeter(len(pointers), totalBytes, false, cfg.Getenv("GIT_LFS_PROGRESS"))
|
|
||||||
|
logPath, _ := cfg.Os.Get("GIT_LFS_PROGRESS")
|
||||||
|
progress := progress.NewProgressMeter(len(pointers), totalBytes, false, logPath)
|
||||||
progress.Start()
|
progress.Start()
|
||||||
totalBytes = 0
|
totalBytes = 0
|
||||||
for _, pointer := range pointers {
|
for _, pointer := range pointers {
|
||||||
|
@ -40,7 +40,7 @@ func envCommand(cmd *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, key := range []string{"filter.lfs.smudge", "filter.lfs.clean"} {
|
for _, key := range []string{"filter.lfs.smudge", "filter.lfs.clean"} {
|
||||||
value, _ := cfg.GitConfig(key)
|
value, _ := cfg.Git.Get(key)
|
||||||
Print("git config %s = %q", key, value)
|
Print("git config %s = %q", key, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ func smudgeCommand(cmd *cobra.Command, args []string) {
|
|||||||
|
|
||||||
download := lfs.FilenamePassesIncludeExcludeFilter(filename, cfg.FetchIncludePaths(), cfg.FetchExcludePaths())
|
download := lfs.FilenamePassesIncludeExcludeFilter(filename, cfg.FetchIncludePaths(), cfg.FetchExcludePaths())
|
||||||
|
|
||||||
if smudgeSkip || cfg.GetenvBool("GIT_LFS_SKIP_SMUDGE", false) {
|
if smudgeSkip || cfg.Os.Bool("GIT_LFS_SKIP_SMUDGE", false) {
|
||||||
download = false
|
download = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,14 +305,14 @@ func usage(cmd *cobra.Command) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// isCommandEnabled returns whether the environment variable GITLFS<CMD>ENABLED
|
// isCommandEnabled returns whether the environment variable GITLFS<CMD>ENABLED
|
||||||
// is "truthy" according to config.GetenvBool (see
|
// is "truthy" according to config.Os.Bool (see
|
||||||
// github.com/github/git-lfs/config#Configuration.GetenvBool), returning false
|
// github.com/github/git-lfs/config#Configuration.Env.Os), returning false
|
||||||
// by default if the enviornment variable is not specified.
|
// by default if the enviornment variable is not specified.
|
||||||
//
|
//
|
||||||
// This function call should only guard commands that do not yet have stable
|
// This function call should only guard commands that do not yet have stable
|
||||||
// APIs or solid server implementations.
|
// APIs or solid server implementations.
|
||||||
func isCommandEnabled(cfg *config.Configuration, cmd string) bool {
|
func isCommandEnabled(cfg *config.Configuration, cmd string) bool {
|
||||||
return cfg.GetenvBool(fmt.Sprintf("GITLFS%sENABLED", strings.ToUpper(cmd)), false)
|
return cfg.Os.Bool(fmt.Sprintf("GITLFS%sENABLED", strings.ToUpper(cmd)), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
117
config/config.go
117
config/config.go
@ -50,14 +50,13 @@ type Configuration struct {
|
|||||||
// Os provides a `*Environment` used to access to the system's
|
// Os provides a `*Environment` used to access to the system's
|
||||||
// environment through os.Getenv. It is the point of entry for all
|
// environment through os.Getenv. It is the point of entry for all
|
||||||
// system environment configuration.
|
// system environment configuration.
|
||||||
Os *Environment
|
Os Environment
|
||||||
|
|
||||||
// Git provides a `*Environment` used to access to the various levels of
|
// Git provides a `*Environment` used to access to the various levels of
|
||||||
// `.gitconfig`'s. It is the point of entry for all Git environment
|
// `.gitconfig`'s. It is the point of entry for all Git environment
|
||||||
// configuration.
|
// configuration.
|
||||||
Git *Environment
|
Git Environment
|
||||||
|
|
||||||
//
|
|
||||||
gitConfig map[string]string
|
gitConfig map[string]string
|
||||||
|
|
||||||
CurrentRemote string
|
CurrentRemote string
|
||||||
@ -79,14 +78,15 @@ type Configuration struct {
|
|||||||
|
|
||||||
func New() *Configuration {
|
func New() *Configuration {
|
||||||
c := &Configuration{
|
c := &Configuration{
|
||||||
Os: EnvironmentOf(NewOsFetcher()),
|
Os: EnvironmentOf(NewOsFetcher()),
|
||||||
|
|
||||||
CurrentRemote: defaultRemote,
|
CurrentRemote: defaultRemote,
|
||||||
envVars: make(map[string]string),
|
envVars: make(map[string]string),
|
||||||
}
|
}
|
||||||
c.IsTracingHttp = c.GetenvBool("GIT_CURL_VERBOSE", false)
|
|
||||||
c.IsDebuggingHttp = c.GetenvBool("LFS_DEBUG_HTTP", false)
|
c.Git = &gitEnvironment{config: c}
|
||||||
c.IsLoggingStats = c.GetenvBool("GIT_LOG_STATS", false)
|
c.IsTracingHttp = c.Os.Bool("GIT_CURL_VERBOSE", false)
|
||||||
|
c.IsDebuggingHttp = c.Os.Bool("LFS_DEBUG_HTTP", false)
|
||||||
|
c.IsLoggingStats = c.Os.Bool("GIT_LOG_STATS", false)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,8 +133,6 @@ func NewFrom(v Values) *Configuration {
|
|||||||
// Otherwise, the field will be set to the value of calling the
|
// Otherwise, the field will be set to the value of calling the
|
||||||
// appropriately-typed method on the specified environment.
|
// appropriately-typed method on the specified environment.
|
||||||
func (c *Configuration) Unmarshal(v interface{}) error {
|
func (c *Configuration) Unmarshal(v interface{}) error {
|
||||||
c.loadGitConfig()
|
|
||||||
|
|
||||||
into := reflect.ValueOf(v)
|
into := reflect.ValueOf(v)
|
||||||
if into.Kind() != reflect.Ptr {
|
if into.Kind() != reflect.Ptr {
|
||||||
return fmt.Errorf("lfs/config: unable to parse non-pointer type of %T", v)
|
return fmt.Errorf("lfs/config: unable to parse non-pointer type of %T", v)
|
||||||
@ -187,7 +185,7 @@ func (c *Configuration) Unmarshal(v interface{}) error {
|
|||||||
// both is not.
|
// both is not.
|
||||||
//
|
//
|
||||||
// If neither field was found, then a nil environment will be returned.
|
// If neither field was found, then a nil environment will be returned.
|
||||||
func (c *Configuration) parseTag(tag reflect.StructTag) (key string, env *Environment, err error) {
|
func (c *Configuration) parseTag(tag reflect.StructTag) (key string, env Environment, err error) {
|
||||||
git, os := tag.Get("git"), tag.Get("os")
|
git, os := tag.Get("git"), tag.Get("os")
|
||||||
|
|
||||||
if len(git) != 0 && len(os) != 0 {
|
if len(git) != 0 && len(os) != 0 {
|
||||||
@ -204,27 +202,16 @@ func (c *Configuration) parseTag(tag reflect.StructTag) (key string, env *Enviro
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getenv is shorthand for `c.Os.Get(key)`.
|
|
||||||
func (c *Configuration) Getenv(key string) string {
|
|
||||||
v, _ := c.Os.Get(key)
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetenvBool is shorthand for `c.Os.Bool(key, def)`.
|
|
||||||
func (c *Configuration) GetenvBool(key string, def bool) bool {
|
|
||||||
return c.Os.Bool(key, def)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GitRemoteUrl returns the git clone/push url for a given remote (blank if not found)
|
// GitRemoteUrl returns the git clone/push url for a given remote (blank if not found)
|
||||||
// the forpush argument is to cater for separate remote.name.pushurl settings
|
// the forpush argument is to cater for separate remote.name.pushurl settings
|
||||||
func (c *Configuration) GitRemoteUrl(remote string, forpush bool) string {
|
func (c *Configuration) GitRemoteUrl(remote string, forpush bool) string {
|
||||||
if forpush {
|
if forpush {
|
||||||
if u, ok := c.GitConfig("remote." + remote + ".pushurl"); ok {
|
if u, ok := c.Git.Get("remote." + remote + ".pushurl"); ok {
|
||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if u, ok := c.GitConfig("remote." + remote + ".url"); ok {
|
if u, ok := c.Git.Get("remote." + remote + ".url"); ok {
|
||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,12 +230,12 @@ func (c *Configuration) Endpoint(operation string) Endpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if operation == "upload" {
|
if operation == "upload" {
|
||||||
if url, ok := c.GitConfig("lfs.pushurl"); ok {
|
if url, ok := c.Git.Get("lfs.pushurl"); ok {
|
||||||
return NewEndpointWithConfig(url, c)
|
return NewEndpointWithConfig(url, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if url, ok := c.GitConfig("lfs.url"); ok {
|
if url, ok := c.Git.Get("lfs.url"); ok {
|
||||||
return NewEndpointWithConfig(url, c)
|
return NewEndpointWithConfig(url, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +255,7 @@ func (c *Configuration) ConcurrentTransfers() int {
|
|||||||
|
|
||||||
uploads := 3
|
uploads := 3
|
||||||
|
|
||||||
if v, ok := c.GitConfig("lfs.concurrenttransfers"); ok {
|
if v, ok := c.Git.Get("lfs.concurrenttransfers"); ok {
|
||||||
n, err := strconv.Atoi(v)
|
n, err := strconv.Atoi(v)
|
||||||
if err == nil && n > 0 {
|
if err == nil && n > 0 {
|
||||||
uploads = n
|
uploads = n
|
||||||
@ -281,17 +268,17 @@ func (c *Configuration) ConcurrentTransfers() int {
|
|||||||
// BasicTransfersOnly returns whether to only allow "basic" HTTP transfers.
|
// BasicTransfersOnly returns whether to only allow "basic" HTTP transfers.
|
||||||
// Default is false, including if the lfs.basictransfersonly is invalid
|
// Default is false, including if the lfs.basictransfersonly is invalid
|
||||||
func (c *Configuration) BasicTransfersOnly() bool {
|
func (c *Configuration) BasicTransfersOnly() bool {
|
||||||
return c.GitConfigBool("lfs.basictransfersonly", false)
|
return c.Git.Bool("lfs.basictransfersonly", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TusTransfersAllowed returns whether to only use "tus.io" HTTP transfers.
|
// TusTransfersAllowed returns whether to only use "tus.io" HTTP transfers.
|
||||||
// Default is false, including if the lfs.tustransfers is invalid
|
// Default is false, including if the lfs.tustransfers is invalid
|
||||||
func (c *Configuration) TusTransfersAllowed() bool {
|
func (c *Configuration) TusTransfersAllowed() bool {
|
||||||
return c.GitConfigBool("lfs.tustransfers", false)
|
return c.Git.Bool("lfs.tustransfers", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Configuration) BatchTransfer() bool {
|
func (c *Configuration) BatchTransfer() bool {
|
||||||
return c.GitConfigBool("lfs.batch", true)
|
return c.Git.Bool("lfs.batch", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Configuration) NtlmAccess(operation string) bool {
|
func (c *Configuration) NtlmAccess(operation string) bool {
|
||||||
@ -337,7 +324,7 @@ func (c *Configuration) SetNetrc(n netrcfinder) {
|
|||||||
|
|
||||||
func (c *Configuration) EndpointAccess(e Endpoint) string {
|
func (c *Configuration) EndpointAccess(e Endpoint) string {
|
||||||
key := fmt.Sprintf("lfs.%s.access", e.Url)
|
key := fmt.Sprintf("lfs.%s.access", e.Url)
|
||||||
if v, ok := c.GitConfig(key); ok && len(v) > 0 {
|
if v, ok := c.Git.Get(key); ok && len(v) > 0 {
|
||||||
lower := strings.ToLower(v)
|
lower := strings.ToLower(v)
|
||||||
if lower == "private" {
|
if lower == "private" {
|
||||||
return "basic"
|
return "basic"
|
||||||
@ -348,6 +335,8 @@ func (c *Configuration) EndpointAccess(e Endpoint) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Configuration) SetEndpointAccess(e Endpoint, authType string) {
|
func (c *Configuration) SetEndpointAccess(e Endpoint, authType string) {
|
||||||
|
c.loadGitConfig()
|
||||||
|
|
||||||
tracerx.Printf("setting repository access to %s", authType)
|
tracerx.Printf("setting repository access to %s", authType)
|
||||||
key := fmt.Sprintf("lfs.%s.access", e.Url)
|
key := fmt.Sprintf("lfs.%s.access", e.Url)
|
||||||
|
|
||||||
@ -370,13 +359,11 @@ func (c *Configuration) SetEndpointAccess(e Endpoint, authType string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Configuration) FetchIncludePaths() []string {
|
func (c *Configuration) FetchIncludePaths() []string {
|
||||||
c.loadGitConfig()
|
|
||||||
patterns, _ := c.Git.Get("lfs.fetchinclude")
|
patterns, _ := c.Git.Get("lfs.fetchinclude")
|
||||||
return tools.CleanPaths(patterns, ",")
|
return tools.CleanPaths(patterns, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Configuration) FetchExcludePaths() []string {
|
func (c *Configuration) FetchExcludePaths() []string {
|
||||||
c.loadGitConfig()
|
|
||||||
patterns, _ := c.Git.Get("lfs.fetchexclude")
|
patterns, _ := c.Git.Get("lfs.fetchexclude")
|
||||||
return tools.CleanPaths(patterns, ",")
|
return tools.CleanPaths(patterns, ",")
|
||||||
}
|
}
|
||||||
@ -388,11 +375,11 @@ func (c *Configuration) RemoteEndpoint(remote, operation string) Endpoint {
|
|||||||
|
|
||||||
// Support separate push URL if specified and pushing
|
// Support separate push URL if specified and pushing
|
||||||
if operation == "upload" {
|
if operation == "upload" {
|
||||||
if url, ok := c.GitConfig("remote." + remote + ".lfspushurl"); ok {
|
if url, ok := c.Git.Get("remote." + remote + ".lfspushurl"); ok {
|
||||||
return NewEndpointWithConfig(url, c)
|
return NewEndpointWithConfig(url, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if url, ok := c.GitConfig("remote." + remote + ".lfsurl"); ok {
|
if url, ok := c.Git.Get("remote." + remote + ".lfsurl"); ok {
|
||||||
return NewEndpointWithConfig(url, c)
|
return NewEndpointWithConfig(url, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,13 +393,14 @@ func (c *Configuration) RemoteEndpoint(remote, operation string) Endpoint {
|
|||||||
|
|
||||||
func (c *Configuration) Remotes() []string {
|
func (c *Configuration) Remotes() []string {
|
||||||
c.loadGitConfig()
|
c.loadGitConfig()
|
||||||
|
|
||||||
return c.remotes
|
return c.remotes
|
||||||
}
|
}
|
||||||
|
|
||||||
// GitProtocol returns the protocol for the LFS API when converting from a
|
// GitProtocol returns the protocol for the LFS API when converting from a
|
||||||
// git:// remote url.
|
// git:// remote url.
|
||||||
func (c *Configuration) GitProtocol() string {
|
func (c *Configuration) GitProtocol() string {
|
||||||
if value, ok := c.GitConfig("lfs.gitprotocol"); ok {
|
if value, ok := c.Git.Get("lfs.gitprotocol"); ok {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
return "https"
|
return "https"
|
||||||
@ -420,6 +408,7 @@ func (c *Configuration) GitProtocol() string {
|
|||||||
|
|
||||||
func (c *Configuration) Extensions() map[string]Extension {
|
func (c *Configuration) Extensions() map[string]Extension {
|
||||||
c.loadGitConfig()
|
c.loadGitConfig()
|
||||||
|
|
||||||
return c.extensions
|
return c.extensions
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,27 +417,9 @@ func (c *Configuration) SortedExtensions() ([]Extension, error) {
|
|||||||
return SortExtensions(c.Extensions())
|
return SortExtensions(c.Extensions())
|
||||||
}
|
}
|
||||||
|
|
||||||
// GitConfigInt parses a git config value and returns it as an integer.
|
|
||||||
func (c *Configuration) GitConfigInt(key string, def int) int {
|
|
||||||
c.loadGitConfig()
|
|
||||||
return c.Git.Int(strings.ToLower(key), def)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GitConfigBool parses a git config value and returns true if defined as
|
|
||||||
// true, 1, on, yes, or def if not defined
|
|
||||||
func (c *Configuration) GitConfigBool(key string, def bool) bool {
|
|
||||||
c.loadGitConfig()
|
|
||||||
return c.Git.Bool(strings.ToLower(key), def)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Configuration) GitConfig(key string) (string, bool) {
|
|
||||||
c.loadGitConfig()
|
|
||||||
value, ok := c.gitConfig[strings.ToLower(key)]
|
|
||||||
return value, ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Configuration) AllGitConfig() map[string]string {
|
func (c *Configuration) AllGitConfig() map[string]string {
|
||||||
c.loadGitConfig()
|
c.loadGitConfig()
|
||||||
|
|
||||||
return c.gitConfig
|
return c.gitConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,30 +482,24 @@ func (c *Configuration) FetchPruneConfig() FetchPruneConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Configuration) SkipDownloadErrors() bool {
|
func (c *Configuration) SkipDownloadErrors() bool {
|
||||||
return c.GetenvBool("GIT_LFS_SKIP_DOWNLOAD_ERRORS", false) || c.GitConfigBool("lfs.skipdownloaderrors", false)
|
return c.Os.Bool("GIT_LFS_SKIP_DOWNLOAD_ERRORS", false) || c.Git.Bool("lfs.skipdownloaderrors", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// loadGitConfig is a temporary measure to support legacy behavior dependent on
|
||||||
|
// accessing properties set by ReadGitConfig, namely:
|
||||||
|
// - `c.extensions`
|
||||||
|
// - `c.uniqRemotes`
|
||||||
|
// - `c.gitConfig`
|
||||||
|
//
|
||||||
|
// Since the *gitEnvironment is responsible for setting these values on the
|
||||||
|
// (*config.Configuration) instance, we must call that method, if it exists.
|
||||||
|
//
|
||||||
|
// loadGitConfig returns a bool returning whether or not `loadGitConfig` was
|
||||||
|
// called AND the method did not return early.
|
||||||
func (c *Configuration) loadGitConfig() bool {
|
func (c *Configuration) loadGitConfig() bool {
|
||||||
c.loading.Lock()
|
if g, ok := c.Git.(*gitEnvironment); ok {
|
||||||
defer c.loading.Unlock()
|
return g.loadGitConfig()
|
||||||
|
|
||||||
if c.Git != nil {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gf, extensions, uniqRemotes := ReadGitConfig(getGitConfigs()...)
|
return false
|
||||||
|
|
||||||
c.Git = EnvironmentOf(gf)
|
|
||||||
c.gitConfig = gf.vals // XXX TERRIBLE
|
|
||||||
c.extensions = extensions
|
|
||||||
|
|
||||||
c.remotes = make([]string, 0, len(uniqRemotes))
|
|
||||||
for remote, isOrigin := range uniqRemotes {
|
|
||||||
if isOrigin {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c.remotes = append(c.remotes, remote)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ func (n *noNetrc) FindMachine(host string) *netrc.Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Configuration) parseNetrc() (netrcfinder, error) {
|
func (c *Configuration) parseNetrc() (netrcfinder, error) {
|
||||||
home := c.Getenv("HOME")
|
home, _ := c.Os.Get("HOME")
|
||||||
if len(home) == 0 {
|
if len(home) == 0 {
|
||||||
return &noNetrc{}, nil
|
return &noNetrc{}, nil
|
||||||
}
|
}
|
||||||
|
@ -11,33 +11,50 @@ import (
|
|||||||
// `Environment`s are the primary way to communicate with various configuration
|
// `Environment`s are the primary way to communicate with various configuration
|
||||||
// sources, such as the OS environment variables, the `.gitconfig`, and even
|
// sources, such as the OS environment variables, the `.gitconfig`, and even
|
||||||
// `map[string]string`s.
|
// `map[string]string`s.
|
||||||
type Environment struct {
|
type Environment interface {
|
||||||
// Fetcher is the `Environment`'s source of data.
|
// Get is shorthand for calling `e.Fetcher.Get(key)`.
|
||||||
|
Get(key string) (val string, ok bool)
|
||||||
|
|
||||||
|
// Bool returns the boolean state associated with a given key, or the
|
||||||
|
// value "def", if no value was associated.
|
||||||
|
//
|
||||||
|
// The "boolean state associated with a given key" is defined as the
|
||||||
|
// case-insensitive string comparison with the following:
|
||||||
|
//
|
||||||
|
// 1) true if...
|
||||||
|
// "true", "1", "on", "yes", or "t"
|
||||||
|
// 2) false if...
|
||||||
|
// "false", "0", "off", "no", "f", or otherwise.
|
||||||
|
Bool(key string, def bool) (val bool)
|
||||||
|
|
||||||
|
// Int returns the int value associated with a given key, or the value
|
||||||
|
// "def", if no value was associated.
|
||||||
|
//
|
||||||
|
// To convert from a the string value attached to a given key,
|
||||||
|
// `strconv.Atoi(val)` is called. If `Atoi` returned a non-nil error,
|
||||||
|
// then the value "def" will be returned instead.
|
||||||
|
//
|
||||||
|
// Otherwise, if the value was converted `string -> int` successfully,
|
||||||
|
// then it will be returned wholesale.
|
||||||
|
Int(key string, def int) (val int)
|
||||||
|
}
|
||||||
|
|
||||||
|
type environment struct {
|
||||||
|
// Fetcher is the `environment`'s source of data.
|
||||||
Fetcher Fetcher
|
Fetcher Fetcher
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnvironmentOf creates a new `*Environment` initialized with the givne
|
// EnvironmentOf creates a new `Environment` initialized with the givne
|
||||||
// `Fetcher`, "f".
|
// `Fetcher`, "f".
|
||||||
func EnvironmentOf(f Fetcher) *Environment {
|
func EnvironmentOf(f Fetcher) Environment {
|
||||||
return &Environment{f}
|
return &environment{f}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get is shorthand for calling `e.Fetcher.Get(key)`.
|
func (e *environment) Get(key string) (val string, ok bool) {
|
||||||
func (e *Environment) Get(key string) (val string, ok bool) {
|
|
||||||
return e.Fetcher.Get(key)
|
return e.Fetcher.Get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool returns the boolean state associated with a given key, or the value
|
func (e *environment) Bool(key string, def bool) (val bool) {
|
||||||
// "def", if no value was associated.
|
|
||||||
//
|
|
||||||
// The "boolean state associated with a given key" is defined as the
|
|
||||||
// case-insensitive string comparison with the following:
|
|
||||||
//
|
|
||||||
// 1) true if...
|
|
||||||
// "true", "1", "on", "yes", or "t"
|
|
||||||
// 2) false if...
|
|
||||||
// "false", "0", "off", "no", "f", or otherwise.
|
|
||||||
func (e *Environment) Bool(key string, def bool) (val bool) {
|
|
||||||
s, _ := e.Fetcher.Get(key)
|
s, _ := e.Fetcher.Get(key)
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
return def
|
return def
|
||||||
@ -53,16 +70,7 @@ func (e *Environment) Bool(key string, def bool) (val bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int returns the int value associated with a given key, or the value "def",
|
func (e *environment) Int(key string, def int) (val int) {
|
||||||
// if no value was associated.
|
|
||||||
//
|
|
||||||
// To convert from a the string value attached to a given key,
|
|
||||||
// `strconv.Atoi(val)` is called. If `Atoi` returned a non-nil error, then the
|
|
||||||
// value "def" will be returned instead.
|
|
||||||
//
|
|
||||||
// Otherwise, if the value was converted `string -> int` successfully, then it
|
|
||||||
// will be returned wholesale.
|
|
||||||
func (e *Environment) Int(key string, def int) (val int) {
|
|
||||||
s, _ := e.Fetcher.Get(key)
|
s, _ := e.Fetcher.Get(key)
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
return def
|
return def
|
||||||
|
@ -7,13 +7,6 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEnvironmentOfReturnsCorrectlyInitializedEnvironment(t *testing.T) {
|
|
||||||
fetcher := MapFetcher(map[string]string{})
|
|
||||||
env := EnvironmentOf(fetcher)
|
|
||||||
|
|
||||||
assert.Equal(t, fetcher, env.Fetcher)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEnvironmentGetDelegatesToFetcher(t *testing.T) {
|
func TestEnvironmentGetDelegatesToFetcher(t *testing.T) {
|
||||||
fetcher := MapFetcher(map[string]string{
|
fetcher := MapFetcher(map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
@ -68,18 +61,18 @@ type EnvironmentConversionTestCase struct {
|
|||||||
Val string
|
Val string
|
||||||
Expected interface{}
|
Expected interface{}
|
||||||
|
|
||||||
GotFn func(env *Environment, key string) interface{}
|
GotFn func(env Environment, key string) interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
GetBoolDefault = func(def bool) func(e *Environment, key string) interface{} {
|
GetBoolDefault = func(def bool) func(e Environment, key string) interface{} {
|
||||||
return func(e *Environment, key string) interface{} {
|
return func(e Environment, key string) interface{} {
|
||||||
return e.Bool(key, def)
|
return e.Bool(key, def)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GetIntDefault = func(def int) func(e *Environment, key string) interface{} {
|
GetIntDefault = func(def int) func(e Environment, key string) interface{} {
|
||||||
return func(e *Environment, key string) interface{} {
|
return func(e Environment, key string) interface{} {
|
||||||
return e.Int(key, def)
|
return e.Int(key, def)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
71
config/git_environment.go
Normal file
71
config/git_environment.go
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
// gitEnvironment is an implementation of the Environment which wraps the legacy
|
||||||
|
// behavior or `*config.Configuration.loadGitConfig()`.
|
||||||
|
//
|
||||||
|
// It is functionally equivelant to call `cfg.loadGitConfig()` before calling
|
||||||
|
// methods on the Environment type.
|
||||||
|
type gitEnvironment struct {
|
||||||
|
// git is the Environment which gitEnvironment wraps.
|
||||||
|
git Environment
|
||||||
|
// config is the *Configuration instance which is mutated by
|
||||||
|
// `loadGitConfig`.
|
||||||
|
config *Configuration
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get is shorthand for calling the loadGitConfig, and then returning
|
||||||
|
// `g.git.Get(key)`.
|
||||||
|
func (g *gitEnvironment) Get(key string) (val string, ok bool) {
|
||||||
|
g.loadGitConfig()
|
||||||
|
|
||||||
|
return g.git.Get(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get is shorthand for calling the loadGitConfig, and then returning
|
||||||
|
// `g.git.Bool(key, def)`.
|
||||||
|
func (g *gitEnvironment) Bool(key string, def bool) (val bool) {
|
||||||
|
g.loadGitConfig()
|
||||||
|
|
||||||
|
return g.git.Bool(key, def)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get is shorthand for calling the loadGitConfig, and then returning
|
||||||
|
// `g.git.Int(key, def)`.
|
||||||
|
func (g *gitEnvironment) Int(key string, def int) (val int) {
|
||||||
|
g.loadGitConfig()
|
||||||
|
|
||||||
|
return g.git.Int(key, def)
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadGitConfig reads and parses the .gitconfig by calling ReadGitConfig. It
|
||||||
|
// also sets values on the configuration instance `g.config`.
|
||||||
|
//
|
||||||
|
// If loadGitConfig has already been called, this method will bail out early,
|
||||||
|
// and return false. Otherwise it will preform the entire parse and return true.
|
||||||
|
//
|
||||||
|
// loadGitConfig is safe to call across multiple goroutines.
|
||||||
|
func (g *gitEnvironment) loadGitConfig() bool {
|
||||||
|
g.config.loading.Lock()
|
||||||
|
defer g.config.loading.Unlock()
|
||||||
|
|
||||||
|
if g.git != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
gf, extensions, uniqRemotes := ReadGitConfig(getGitConfigs()...)
|
||||||
|
|
||||||
|
g.git = EnvironmentOf(gf)
|
||||||
|
|
||||||
|
g.config.gitConfig = gf.vals // XXX TERRIBLE
|
||||||
|
g.config.extensions = extensions
|
||||||
|
|
||||||
|
g.config.remotes = make([]string, 0, len(uniqRemotes))
|
||||||
|
for remote, isOrigin := range uniqRemotes {
|
||||||
|
if isOrigin {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
g.config.remotes = append(g.config.remotes, remote)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
@ -110,11 +110,19 @@ func ReadGitConfig(configs ...*GitConfig) (gf *GitFetcher, extensions map[string
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get implements the Fetcher interface, and returns the value associated with
|
||||||
|
// a given key and true, signaling that the value was present. Otherwise, an
|
||||||
|
// empty string and false will be returned, signaling that the value was
|
||||||
|
// absent.
|
||||||
|
//
|
||||||
|
// Map lookup by key is case-insensitive, as per the .gitconfig specification.
|
||||||
|
//
|
||||||
|
// Get is safe to call across multiple goroutines.
|
||||||
func (g *GitFetcher) Get(key string) (val string, ok bool) {
|
func (g *GitFetcher) Get(key string) (val string, ok bool) {
|
||||||
g.vmu.RLock()
|
g.vmu.RLock()
|
||||||
defer g.vmu.RUnlock()
|
defer g.vmu.RUnlock()
|
||||||
|
|
||||||
val, ok = g.vals[key]
|
val, ok = g.vals[strings.ToLower(key)]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,13 +13,13 @@ import (
|
|||||||
// isCertVerificationDisabledForHost returns whether SSL certificate verification
|
// isCertVerificationDisabledForHost returns whether SSL certificate verification
|
||||||
// has been disabled for the given host, or globally
|
// has been disabled for the given host, or globally
|
||||||
func isCertVerificationDisabledForHost(cfg *config.Configuration, host string) bool {
|
func isCertVerificationDisabledForHost(cfg *config.Configuration, host string) bool {
|
||||||
hostSslVerify, _ := cfg.GitConfig(fmt.Sprintf("http.https://%v/.sslverify", host))
|
hostSslVerify, _ := cfg.Git.Get(fmt.Sprintf("http.https://%v/.sslverify", host))
|
||||||
if hostSslVerify == "false" {
|
if hostSslVerify == "false" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
globalSslVerify, _ := cfg.GitConfig("http.sslverify")
|
globalSslVerify, _ := cfg.Git.Get("http.sslverify")
|
||||||
if globalSslVerify == "false" || cfg.GetenvBool("GIT_SSL_NO_VERIFY", false) {
|
if globalSslVerify == "false" || cfg.Os.Bool("GIT_SSL_NO_VERIFY", false) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,29 +48,29 @@ func appendRootCAsForHostFromGitconfig(cfg *config.Configuration, pool *x509.Cer
|
|||||||
// Accumulate certs from all these locations:
|
// Accumulate certs from all these locations:
|
||||||
|
|
||||||
// GIT_SSL_CAINFO first
|
// GIT_SSL_CAINFO first
|
||||||
if cafile := cfg.Getenv("GIT_SSL_CAINFO"); len(cafile) > 0 {
|
if cafile, _ := cfg.Os.Get("GIT_SSL_CAINFO"); len(cafile) > 0 {
|
||||||
return appendCertsFromFile(pool, cafile)
|
return appendCertsFromFile(pool, cafile)
|
||||||
}
|
}
|
||||||
// http.<url>/.sslcainfo or http.<url>.sslcainfo
|
// http.<url>/.sslcainfo or http.<url>.sslcainfo
|
||||||
// we know we have simply "host" or "host:port"
|
// we know we have simply "host" or "host:port"
|
||||||
hostKeyWithSlash := fmt.Sprintf("http.https://%v/.sslcainfo", host)
|
hostKeyWithSlash := fmt.Sprintf("http.https://%v/.sslcainfo", host)
|
||||||
if cafile, ok := cfg.GitConfig(hostKeyWithSlash); ok {
|
if cafile, ok := cfg.Git.Get(hostKeyWithSlash); ok {
|
||||||
return appendCertsFromFile(pool, cafile)
|
return appendCertsFromFile(pool, cafile)
|
||||||
}
|
}
|
||||||
hostKeyWithoutSlash := fmt.Sprintf("http.https://%v.sslcainfo", host)
|
hostKeyWithoutSlash := fmt.Sprintf("http.https://%v.sslcainfo", host)
|
||||||
if cafile, ok := cfg.GitConfig(hostKeyWithoutSlash); ok {
|
if cafile, ok := cfg.Git.Get(hostKeyWithoutSlash); ok {
|
||||||
return appendCertsFromFile(pool, cafile)
|
return appendCertsFromFile(pool, cafile)
|
||||||
}
|
}
|
||||||
// http.sslcainfo
|
// http.sslcainfo
|
||||||
if cafile, ok := cfg.GitConfig("http.sslcainfo"); ok {
|
if cafile, ok := cfg.Git.Get("http.sslcainfo"); ok {
|
||||||
return appendCertsFromFile(pool, cafile)
|
return appendCertsFromFile(pool, cafile)
|
||||||
}
|
}
|
||||||
// GIT_SSL_CAPATH
|
// GIT_SSL_CAPATH
|
||||||
if cadir := cfg.Getenv("GIT_SSL_CAPATH"); len(cadir) > 0 {
|
if cadir, _ := cfg.Os.Get("GIT_SSL_CAPATH"); len(cadir) > 0 {
|
||||||
return appendCertsFromFilesInDir(pool, cadir)
|
return appendCertsFromFilesInDir(pool, cadir)
|
||||||
}
|
}
|
||||||
// http.sslcapath
|
// http.sslcapath
|
||||||
if cadir, ok := cfg.GitConfig("http.sslcapath"); ok {
|
if cadir, ok := cfg.Git.Get("http.sslcapath"); ok {
|
||||||
return appendCertsFromFilesInDir(pool, cadir)
|
return appendCertsFromFilesInDir(pool, cadir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,9 +117,9 @@ func NewHttpClient(c *config.Configuration, host string) *HttpClient {
|
|||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
dialtime := c.GitConfigInt("lfs.dialtimeout", 30)
|
dialtime := c.Git.Int("lfs.dialtimeout", 30)
|
||||||
keepalivetime := c.GitConfigInt("lfs.keepalive", 1800) // 30 minutes
|
keepalivetime := c.Git.Int("lfs.keepalive", 1800) // 30 minutes
|
||||||
tlstime := c.GitConfigInt("lfs.tlstimeout", 30)
|
tlstime := c.Git.Int("lfs.tlstimeout", 30)
|
||||||
|
|
||||||
tr := &http.Transport{
|
tr := &http.Transport{
|
||||||
Proxy: ProxyFromGitConfigOrEnvironment(c),
|
Proxy: ProxyFromGitConfigOrEnvironment(c),
|
||||||
|
@ -14,30 +14,30 @@ import (
|
|||||||
// Logic is copied, with small changes, from "net/http".ProxyFromEnvironment in the go std lib.
|
// Logic is copied, with small changes, from "net/http".ProxyFromEnvironment in the go std lib.
|
||||||
func ProxyFromGitConfigOrEnvironment(c *config.Configuration) func(req *http.Request) (*url.URL, error) {
|
func ProxyFromGitConfigOrEnvironment(c *config.Configuration) func(req *http.Request) (*url.URL, error) {
|
||||||
var https_proxy string
|
var https_proxy string
|
||||||
http_proxy, _ := c.GitConfig("http.proxy")
|
http_proxy, _ := c.Git.Get("http.proxy")
|
||||||
if strings.HasPrefix(http_proxy, "https://") {
|
if strings.HasPrefix(http_proxy, "https://") {
|
||||||
https_proxy = http_proxy
|
https_proxy = http_proxy
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(https_proxy) == 0 {
|
if len(https_proxy) == 0 {
|
||||||
https_proxy = c.Getenv("HTTPS_PROXY")
|
https_proxy, _ = c.Os.Get("HTTPS_PROXY")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(https_proxy) == 0 {
|
if len(https_proxy) == 0 {
|
||||||
https_proxy = c.Getenv("https_proxy")
|
https_proxy, _ = c.Os.Get("https_proxy")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(http_proxy) == 0 {
|
if len(http_proxy) == 0 {
|
||||||
http_proxy = c.Getenv("HTTP_PROXY")
|
http_proxy, _ = c.Os.Get("HTTP_PROXY")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(http_proxy) == 0 {
|
if len(http_proxy) == 0 {
|
||||||
http_proxy = c.Getenv("http_proxy")
|
http_proxy, _ = c.Os.Get("http_proxy")
|
||||||
}
|
}
|
||||||
|
|
||||||
no_proxy := c.Getenv("NO_PROXY")
|
no_proxy, _ := c.Os.Get("NO_PROXY")
|
||||||
if len(no_proxy) == 0 {
|
if len(no_proxy) == 0 {
|
||||||
no_proxy = c.Getenv("no_proxy")
|
no_proxy, _ = c.Os.Get("no_proxy")
|
||||||
}
|
}
|
||||||
|
|
||||||
return func(req *http.Request) (*url.URL, error) {
|
return func(req *http.Request) (*url.URL, error) {
|
||||||
|
@ -39,7 +39,7 @@ func (h *Hook) Path() string {
|
|||||||
// greater than "2.9.0"), it will return that instead.
|
// greater than "2.9.0"), it will return that instead.
|
||||||
func (h *Hook) Dir() string {
|
func (h *Hook) Dir() string {
|
||||||
customHooksSupported := git.Config.IsGitVersionAtLeast("2.9.0")
|
customHooksSupported := git.Config.IsGitVersionAtLeast("2.9.0")
|
||||||
if hp, ok := config.Config.GitConfig("core.hooksPath"); ok && customHooksSupported {
|
if hp, ok := config.Config.Git.Get("core.hooksPath"); ok && customHooksSupported {
|
||||||
return hp
|
return hp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,10 +58,12 @@ type TransferQueue struct {
|
|||||||
|
|
||||||
// newTransferQueue builds a TransferQueue, direction and underlying mechanism determined by adapter
|
// newTransferQueue builds a TransferQueue, direction and underlying mechanism determined by adapter
|
||||||
func newTransferQueue(files int, size int64, dryRun bool, dir transfer.Direction) *TransferQueue {
|
func newTransferQueue(files int, size int64, dryRun bool, dir transfer.Direction) *TransferQueue {
|
||||||
|
logPath, _ := config.Config.Os.Get("GIT_LFS_PROGRESS")
|
||||||
|
|
||||||
q := &TransferQueue{
|
q := &TransferQueue{
|
||||||
direction: dir,
|
direction: dir,
|
||||||
dryRun: dryRun,
|
dryRun: dryRun,
|
||||||
meter: progress.NewProgressMeter(files, size, dryRun, config.Config.Getenv("GIT_LFS_PROGRESS")),
|
meter: progress.NewProgressMeter(files, size, dryRun, logPath),
|
||||||
apic: make(chan Transferable, batchSize),
|
apic: make(chan Transferable, batchSize),
|
||||||
retriesc: make(chan Transferable, batchSize),
|
retriesc: make(chan Transferable, batchSize),
|
||||||
errorc: make(chan error),
|
errorc: make(chan error),
|
||||||
|
@ -27,7 +27,7 @@ const (
|
|||||||
var currentPlatform = PlatformUndetermined
|
var currentPlatform = PlatformUndetermined
|
||||||
|
|
||||||
func CopyCallbackFile(event, filename string, index, totalFiles int) (progress.CopyCallback, *os.File, error) {
|
func CopyCallbackFile(event, filename string, index, totalFiles int) (progress.CopyCallback, *os.File, error) {
|
||||||
logPath := config.Config.Getenv("GIT_LFS_PROGRESS")
|
logPath, _ := config.Config.Os.Get("GIT_LFS_PROGRESS")
|
||||||
if len(logPath) == 0 || len(filename) == 0 || len(event) == 0 {
|
if len(logPath) == 0 || len(filename) == 0 || len(event) == 0 {
|
||||||
return nil, nil, nil
|
return nil, nil, nil
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ type customAdapterWorkerContext struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type customAdapterInitRequest struct {
|
type customAdapterInitRequest struct {
|
||||||
Event string `json:"Event"`
|
Event string `json:"event"`
|
||||||
Operation string `json:"operation"`
|
Operation string `json:"operation"`
|
||||||
Concurrent bool `json:"concurrent"`
|
Concurrent bool `json:"concurrent"`
|
||||||
ConcurrentTransfers int `json:"concurrenttransfers"`
|
ConcurrentTransfers int `json:"concurrenttransfers"`
|
||||||
@ -358,9 +358,9 @@ func configureCustomAdapters(cfg *config.Configuration, m *Manifest) {
|
|||||||
name := match[1]
|
name := match[1]
|
||||||
path := v
|
path := v
|
||||||
// retrieve other values
|
// retrieve other values
|
||||||
args, _ := cfg.GitConfig(fmt.Sprintf("lfs.customtransfer.%s.args", name))
|
args, _ := cfg.Git.Get(fmt.Sprintf("lfs.customtransfer.%s.args", name))
|
||||||
concurrent := cfg.GitConfigBool(fmt.Sprintf("lfs.customtransfer.%s.concurrent", name), true)
|
concurrent := cfg.Git.Bool(fmt.Sprintf("lfs.customtransfer.%s.concurrent", name), true)
|
||||||
direction, _ := cfg.GitConfig(fmt.Sprintf("lfs.customtransfer.%s.direction", name))
|
direction, _ := cfg.Git.Get(fmt.Sprintf("lfs.customtransfer.%s.direction", name))
|
||||||
if len(direction) == 0 {
|
if len(direction) == 0 {
|
||||||
direction = "both"
|
direction = "both"
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user