From 98af5944e1608ba5dd3e9c8668518b9773019cbf Mon Sep 17 00:00:00 2001 From: risk danger olson Date: Wed, 10 Aug 2016 09:33:25 -0600 Subject: [PATCH 01/12] build commands outside of package init() --- commands/command_checkout.go | 20 +++++------ commands/command_clean.go | 14 ++++---- commands/command_clone.go | 67 ++++++++++++++++++----------------- commands/command_env.go | 14 ++++---- commands/command_ext.go | 28 +++++++-------- commands/command_fetch.go | 29 ++++++++------- commands/command_fsck.go | 16 +++++---- commands/command_init.go | 33 ++++++++--------- commands/command_install.go | 30 ++++++++-------- commands/command_lock.go | 21 ++++++----- commands/command_locks.go | 34 +++++++++--------- commands/command_logs.go | 55 ++++++++++++++-------------- commands/command_ls_files.go | 17 +++++---- commands/command_pointer.go | 20 ++++++----- commands/command_pre_push.go | 15 ++++---- commands/command_prune.go | 23 ++++++------ commands/command_pull.go | 20 +++++------ commands/command_push.go | 20 ++++++----- commands/command_smudge.go | 18 +++++----- commands/command_status.go | 15 ++++---- commands/command_track.go | 17 ++++----- commands/command_uninit.go | 30 ++++++++-------- commands/command_uninstall.go | 30 ++++++++-------- commands/command_unlock.go | 23 ++++++------ commands/command_untrack.go | 14 ++++---- commands/command_update.go | 17 ++++----- commands/command_version.go | 16 +++++---- commands/commands.go | 61 +++++++++++++++++++++---------- 28 files changed, 378 insertions(+), 339 deletions(-) diff --git a/commands/command_checkout.go b/commands/command_checkout.go index b6113820..d0b45345 100644 --- a/commands/command_checkout.go +++ b/commands/command_checkout.go @@ -16,13 +16,6 @@ import ( "github.com/spf13/cobra" ) -var ( - checkoutCmd = &cobra.Command{ - Use: "checkout", - Run: checkoutCommand, - } -) - func checkoutCommand(cmd *cobra.Command, args []string) { requireInRepo() @@ -43,10 +36,6 @@ func checkoutCommand(cmd *cobra.Command, args []string) { checkoutWithIncludeExclude(rootedpaths, nil) } -func init() { - RootCmd.AddCommand(checkoutCmd) -} - // Checkout from items reported from the fetch process (in parallel) func checkoutAllFromFetchChan(c chan *lfs.WrappedPointer) { tracerx.Printf("starting fetch/parallel checkout") @@ -239,3 +228,12 @@ func checkoutWithChan(in <-chan *lfs.WrappedPointer) { } } } + +func init() { + RegisterSubcommand(func() *cobra.Command { + return &cobra.Command{ + Use: "checkout", + Run: checkoutCommand, + } + }) +} diff --git a/commands/command_clean.go b/commands/command_clean.go index a0dea529..30b2d5d6 100644 --- a/commands/command_clean.go +++ b/commands/command_clean.go @@ -9,13 +9,6 @@ import ( "github.com/spf13/cobra" ) -var ( - cleanCmd = &cobra.Command{ - Use: "clean", - Run: cleanCommand, - } -) - func cleanCommand(cmd *cobra.Command, args []string) { requireStdin("This command should be run by the Git 'clean' filter") lfs.InstallHooks(false) @@ -82,5 +75,10 @@ func cleanCommand(cmd *cobra.Command, args []string) { } func init() { - RootCmd.AddCommand(cleanCmd) + RegisterSubcommand(func() *cobra.Command { + return &cobra.Command{ + Use: "clean", + Run: cleanCommand, + } + }) } diff --git a/commands/command_clone.go b/commands/command_clone.go index 7f165a50..dd0a37bb 100644 --- a/commands/command_clone.go +++ b/commands/command_clone.go @@ -15,11 +15,6 @@ import ( ) var ( - cloneCmd = &cobra.Command{ - Use: "clone", - Run: cloneCommand, - } - cloneFlags git.CloneFlags ) @@ -112,34 +107,40 @@ func postCloneSubmodules(args []string) error { } func init() { - // Mirror all git clone flags - cloneCmd.Flags().StringVarP(&cloneFlags.TemplateDirectory, "template", "", "", "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.Local, "local", "l", false, "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.Shared, "shared", "s", false, "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.NoHardlinks, "no-hardlinks", "", false, "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.Quiet, "quiet", "q", false, "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.NoCheckout, "no-checkout", "n", false, "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.Progress, "progress", "", false, "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.Bare, "bare", "", false, "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.Mirror, "mirror", "", false, "See 'git clone --help'") - cloneCmd.Flags().StringVarP(&cloneFlags.Origin, "origin", "o", "", "See 'git clone --help'") - cloneCmd.Flags().StringVarP(&cloneFlags.Branch, "branch", "b", "", "See 'git clone --help'") - cloneCmd.Flags().StringVarP(&cloneFlags.Upload, "upload-pack", "u", "", "See 'git clone --help'") - cloneCmd.Flags().StringVarP(&cloneFlags.Reference, "reference", "", "", "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.Dissociate, "dissociate", "", false, "See 'git clone --help'") - cloneCmd.Flags().StringVarP(&cloneFlags.SeparateGit, "separate-git-dir", "", "", "See 'git clone --help'") - cloneCmd.Flags().StringVarP(&cloneFlags.Depth, "depth", "", "", "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.Recursive, "recursive", "", false, "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.RecurseSubmodules, "recurse-submodules", "", false, "See 'git clone --help'") - cloneCmd.Flags().StringVarP(&cloneFlags.Config, "config", "c", "", "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.SingleBranch, "single-branch", "", false, "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.NoSingleBranch, "no-single-branch", "", false, "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.Verbose, "verbose", "", false, "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.Ipv4, "ipv4", "", false, "See 'git clone --help'") - cloneCmd.Flags().BoolVarP(&cloneFlags.Ipv6, "ipv6", "", false, "See 'git clone --help'") + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "clone", + Run: cloneCommand, + } - cloneCmd.Flags().StringVarP(&includeArg, "include", "I", "", "Include a list of paths") - cloneCmd.Flags().StringVarP(&excludeArg, "exclude", "X", "", "Exclude a list of paths") + // Mirror all git clone flags + cmd.Flags().StringVarP(&cloneFlags.TemplateDirectory, "template", "", "", "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.Local, "local", "l", false, "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.Shared, "shared", "s", false, "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.NoHardlinks, "no-hardlinks", "", false, "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.Quiet, "quiet", "q", false, "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.NoCheckout, "no-checkout", "n", false, "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.Progress, "progress", "", false, "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.Bare, "bare", "", false, "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.Mirror, "mirror", "", false, "See 'git clone --help'") + cmd.Flags().StringVarP(&cloneFlags.Origin, "origin", "o", "", "See 'git clone --help'") + cmd.Flags().StringVarP(&cloneFlags.Branch, "branch", "b", "", "See 'git clone --help'") + cmd.Flags().StringVarP(&cloneFlags.Upload, "upload-pack", "u", "", "See 'git clone --help'") + cmd.Flags().StringVarP(&cloneFlags.Reference, "reference", "", "", "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.Dissociate, "dissociate", "", false, "See 'git clone --help'") + cmd.Flags().StringVarP(&cloneFlags.SeparateGit, "separate-git-dir", "", "", "See 'git clone --help'") + cmd.Flags().StringVarP(&cloneFlags.Depth, "depth", "", "", "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.Recursive, "recursive", "", false, "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.RecurseSubmodules, "recurse-submodules", "", false, "See 'git clone --help'") + cmd.Flags().StringVarP(&cloneFlags.Config, "config", "c", "", "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.SingleBranch, "single-branch", "", false, "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.NoSingleBranch, "no-single-branch", "", false, "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.Verbose, "verbose", "", false, "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.Ipv4, "ipv4", "", false, "See 'git clone --help'") + cmd.Flags().BoolVarP(&cloneFlags.Ipv6, "ipv6", "", false, "See 'git clone --help'") - RootCmd.AddCommand(cloneCmd) + cmd.Flags().StringVarP(&includeArg, "include", "I", "", "Include a list of paths") + cmd.Flags().StringVarP(&excludeArg, "exclude", "X", "", "Exclude a list of paths") + return cmd + }) } diff --git a/commands/command_env.go b/commands/command_env.go index 25d54ebc..2107861b 100644 --- a/commands/command_env.go +++ b/commands/command_env.go @@ -7,13 +7,6 @@ import ( "github.com/spf13/cobra" ) -var ( - envCmd = &cobra.Command{ - Use: "env", - Run: envCommand, - } -) - func envCommand(cmd *cobra.Command, args []string) { config.ShowConfigWarnings = true endpoint := cfg.Endpoint("download") @@ -53,5 +46,10 @@ func envCommand(cmd *cobra.Command, args []string) { } func init() { - RootCmd.AddCommand(envCmd) + RegisterSubcommand(func() *cobra.Command { + return &cobra.Command{ + Use: "env", + Run: envCommand, + } + }) } diff --git a/commands/command_ext.go b/commands/command_ext.go index 7e975a35..66521791 100644 --- a/commands/command_ext.go +++ b/commands/command_ext.go @@ -7,19 +7,6 @@ import ( "github.com/spf13/cobra" ) -var ( - extCmd = &cobra.Command{ - Use: "ext", - Run: extCommand, - } - - extListCmd = &cobra.Command{ - Use: "list", - Short: "View details for specified extensions", - Run: extListCommand, - } -) - func extCommand(cmd *cobra.Command, args []string) { printAllExts() } @@ -56,6 +43,17 @@ func printExt(ext config.Extension) { } func init() { - extCmd.AddCommand(extListCmd) - RootCmd.AddCommand(extCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "ext", + Run: extCommand, + } + + cmd.AddCommand(&cobra.Command{ + Use: "list", + Short: "View details for specified extensions", + Run: extListCommand, + }) + return cmd + }) } diff --git a/commands/command_fetch.go b/commands/command_fetch.go index ec94d650..06b510f7 100644 --- a/commands/command_fetch.go +++ b/commands/command_fetch.go @@ -12,10 +12,6 @@ import ( ) var ( - fetchCmd = &cobra.Command{ - Use: "fetch", - Run: fetchCommand, - } fetchRecentArg bool fetchAllArg bool fetchPruneArg bool @@ -111,15 +107,6 @@ func fetchCommand(cmd *cobra.Command, args []string) { } } -func init() { - fetchCmd.Flags().StringVarP(&includeArg, "include", "I", "", "Include a list of paths") - fetchCmd.Flags().StringVarP(&excludeArg, "exclude", "X", "", "Exclude a list of paths") - fetchCmd.Flags().BoolVarP(&fetchRecentArg, "recent", "r", false, "Fetch recent refs & commits") - fetchCmd.Flags().BoolVarP(&fetchAllArg, "all", "a", false, "Fetch all LFS files ever referenced") - fetchCmd.Flags().BoolVarP(&fetchPruneArg, "prune", "p", false, "After fetching, prune old data") - RootCmd.AddCommand(fetchCmd) -} - func pointersToFetchForRef(ref string) ([]*lfs.WrappedPointer, error) { // Use SkipDeletedBlobs to avoid fetching ALL previous versions of modified files opts := lfs.NewScanRefsOptions() @@ -330,3 +317,19 @@ func fetchAndReportToChan(pointers []*lfs.WrappedPointer, include, exclude []str } return ok } + +func init() { + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "fetch", + Run: fetchCommand, + } + + cmd.Flags().StringVarP(&includeArg, "include", "I", "", "Include a list of paths") + cmd.Flags().StringVarP(&excludeArg, "exclude", "X", "", "Exclude a list of paths") + cmd.Flags().BoolVarP(&fetchRecentArg, "recent", "r", false, "Fetch recent refs & commits") + cmd.Flags().BoolVarP(&fetchAllArg, "all", "a", false, "Fetch all LFS files ever referenced") + cmd.Flags().BoolVarP(&fetchPruneArg, "prune", "p", false, "After fetching, prune old data") + return cmd + }) +} diff --git a/commands/command_fsck.go b/commands/command_fsck.go index 7f620f53..2ec8ecb2 100644 --- a/commands/command_fsck.go +++ b/commands/command_fsck.go @@ -15,11 +15,6 @@ import ( var ( fsckDryRun bool - - fsckCmd = &cobra.Command{ - Use: "fsck", - Run: fsckCommand, - } ) func doFsck() (bool, error) { @@ -120,6 +115,13 @@ func fsckCommand(cmd *cobra.Command, args []string) { } func init() { - fsckCmd.Flags().BoolVarP(&fsckDryRun, "dry-run", "d", false, "List corrupt objects without deleting them.") - RootCmd.AddCommand(fsckCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "fsck", + Run: fsckCommand, + } + + cmd.Flags().BoolVarP(&fsckDryRun, "dry-run", "d", false, "List corrupt objects without deleting them.") + return cmd + }) } diff --git a/commands/command_init.go b/commands/command_init.go index 65caf8d2..3286d7f6 100644 --- a/commands/command_init.go +++ b/commands/command_init.go @@ -8,19 +8,6 @@ import ( ) // TODO: Remove for Git LFS v2.0 https://github.com/github/git-lfs/issues/839 - -var ( - initCmd = &cobra.Command{ - Use: "init", - Run: initCommand, - } - - initHooksCmd = &cobra.Command{ - Use: "hooks", - Run: initHooksCommand, - } -) - func initCommand(cmd *cobra.Command, args []string) { fmt.Fprintf(os.Stderr, "WARNING: 'git lfs init' is deprecated. Use 'git lfs install' now.\n") installCommand(cmd, args) @@ -32,9 +19,19 @@ func initHooksCommand(cmd *cobra.Command, args []string) { } func init() { - initCmd.Flags().BoolVarP(&forceInstall, "force", "f", false, "Set the Git LFS global config, overwriting previous values.") - initCmd.Flags().BoolVarP(&localInstall, "local", "l", false, "Set the Git LFS config for the local Git repository only.") - initCmd.Flags().BoolVarP(&skipSmudgeInstall, "skip-smudge", "s", false, "Skip automatic downloading of objects on clone or pull.") - initCmd.AddCommand(initHooksCmd) - RootCmd.AddCommand(initCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "init", + Run: initCommand, + } + + cmd.Flags().BoolVarP(&forceInstall, "force", "f", false, "Set the Git LFS global config, overwriting previous values.") + cmd.Flags().BoolVarP(&localInstall, "local", "l", false, "Set the Git LFS config for the local Git repository only.") + cmd.Flags().BoolVarP(&skipSmudgeInstall, "skip-smudge", "s", false, "Skip automatic downloading of objects on clone or pull.") + cmd.AddCommand(&cobra.Command{ + Use: "hooks", + Run: initHooksCommand, + }) + return cmd + }) } diff --git a/commands/command_install.go b/commands/command_install.go index 692b7124..d3099711 100644 --- a/commands/command_install.go +++ b/commands/command_install.go @@ -6,16 +6,6 @@ import ( ) var ( - installCmd = &cobra.Command{ - Use: "install", - Run: installCommand, - } - - installHooksCmd = &cobra.Command{ - Use: "hooks", - Run: installHooksCommand, - } - forceInstall = false localInstall = false skipSmudgeInstall = false @@ -50,9 +40,19 @@ func installHooksCommand(cmd *cobra.Command, args []string) { } func init() { - installCmd.Flags().BoolVarP(&forceInstall, "force", "f", false, "Set the Git LFS global config, overwriting previous values.") - installCmd.Flags().BoolVarP(&localInstall, "local", "l", false, "Set the Git LFS config for the local Git repository only.") - installCmd.Flags().BoolVarP(&skipSmudgeInstall, "skip-smudge", "s", false, "Skip automatic downloading of objects on clone or pull.") - installCmd.AddCommand(installHooksCmd) - RootCmd.AddCommand(installCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "install", + Run: installCommand, + } + + cmd.Flags().BoolVarP(&forceInstall, "force", "f", false, "Set the Git LFS global config, overwriting previous values.") + cmd.Flags().BoolVarP(&localInstall, "local", "l", false, "Set the Git LFS config for the local Git repository only.") + cmd.Flags().BoolVarP(&skipSmudgeInstall, "skip-smudge", "s", false, "Skip automatic downloading of objects on clone or pull.") + cmd.AddCommand(&cobra.Command{ + Use: "hooks", + Run: installHooksCommand, + }) + return cmd + }) } diff --git a/commands/command_lock.go b/commands/command_lock.go index cfba9cb5..b203cdb7 100644 --- a/commands/command_lock.go +++ b/commands/command_lock.go @@ -22,11 +22,6 @@ var ( setLockRemoteFor = func(c *config.Configuration) { c.CurrentRemote = lockRemote } - - lockCmd = &cobra.Command{ - Use: "lock", - Run: lockCommand, - } ) func lockCommand(cmd *cobra.Command, args []string) { @@ -107,9 +102,17 @@ func lockPath(file string) (string, error) { } func init() { - lockCmd.Flags().StringVarP(&lockRemote, "remote", "r", cfg.CurrentRemote, lockRemoteHelp) + RegisterSubcommand(func() *cobra.Command { + if !isCommandEnabled(cfg, "locks") { + return nil + } - if isCommandEnabled(cfg, "locks") { - RootCmd.AddCommand(lockCmd) - } + cmd := &cobra.Command{ + Use: "lock", + Run: lockCommand, + } + + cmd.Flags().StringVarP(&lockRemote, "remote", "r", cfg.CurrentRemote, lockRemoteHelp) + return cmd + }) } diff --git a/commands/command_locks.go b/commands/command_locks.go index 9ee167f8..e903f4a3 100644 --- a/commands/command_locks.go +++ b/commands/command_locks.go @@ -7,10 +7,6 @@ import ( var ( locksCmdFlags = new(locksFlags) - locksCmd = &cobra.Command{ - Use: "locks", - Run: locksCommand, - } ) func locksCommand(cmd *cobra.Command, args []string) { @@ -55,18 +51,6 @@ func locksCommand(cmd *cobra.Command, args []string) { } } -func init() { - locksCmd.Flags().StringVarP(&lockRemote, "remote", "r", cfg.CurrentRemote, lockRemoteHelp) - - locksCmd.Flags().StringVarP(&locksCmdFlags.Path, "path", "p", "", "filter locks results matching a particular path") - locksCmd.Flags().StringVarP(&locksCmdFlags.Id, "id", "i", "", "filter locks results matching a particular ID") - locksCmd.Flags().IntVarP(&locksCmdFlags.Limit, "limit", "l", 0, "optional limit for number of results to return") - - if isCommandEnabled(cfg, "locks") { - RootCmd.AddCommand(locksCmd) - } -} - // locksFlags wraps up and holds all of the flags that can be given to the // `git lfs locks` command. type locksFlags struct { @@ -101,3 +85,21 @@ func (l *locksFlags) Filters() ([]api.Filter, error) { return filters, nil } + +func init() { + RegisterSubcommand(func() *cobra.Command { + if !isCommandEnabled(cfg, "locks") { + return nil + } + cmd := &cobra.Command{ + Use: "locks", + Run: locksCommand, + } + + cmd.Flags().StringVarP(&lockRemote, "remote", "r", cfg.CurrentRemote, lockRemoteHelp) + cmd.Flags().StringVarP(&locksCmdFlags.Path, "path", "p", "", "filter locks results matching a particular path") + cmd.Flags().StringVarP(&locksCmdFlags.Id, "id", "i", "", "filter locks results matching a particular ID") + cmd.Flags().IntVarP(&locksCmdFlags.Limit, "limit", "l", 0, "optional limit for number of results to return") + return cmd + }) +} diff --git a/commands/command_logs.go b/commands/command_logs.go index 8eb477e8..e2d7bc47 100644 --- a/commands/command_logs.go +++ b/commands/command_logs.go @@ -11,33 +11,6 @@ import ( "github.com/spf13/cobra" ) -var ( - logsCmd = &cobra.Command{ - Use: "logs", - Run: logsCommand, - } - - logsLastCmd = &cobra.Command{ - Use: "last", - Run: logsLastCommand, - } - - logsShowCmd = &cobra.Command{ - Use: "show", - Run: logsShowCommand, - } - - logsClearCmd = &cobra.Command{ - Use: "clear", - Run: logsClearCommand, - } - - logsBoomtownCmd = &cobra.Command{ - Use: "boomtown", - Run: logsBoomtownCommand, - } -) - func logsCommand(cmd *cobra.Command, args []string) { for _, path := range sortedLogs() { Print(path) @@ -104,6 +77,30 @@ func sortedLogs() []string { } func init() { - logsCmd.AddCommand(logsLastCmd, logsShowCmd, logsClearCmd, logsBoomtownCmd) - RootCmd.AddCommand(logsCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "logs", + Run: logsCommand, + } + + cmd.AddCommand( + &cobra.Command{ + Use: "last", + Run: logsLastCommand, + }, + &cobra.Command{ + Use: "show", + Run: logsShowCommand, + }, + &cobra.Command{ + Use: "clear", + Run: logsClearCommand, + }, + &cobra.Command{ + Use: "boomtown", + Run: logsBoomtownCommand, + }, + ) + return cmd + }) } diff --git a/commands/command_ls_files.go b/commands/command_ls_files.go index 935acf8f..90210481 100644 --- a/commands/command_ls_files.go +++ b/commands/command_ls_files.go @@ -9,11 +9,7 @@ import ( ) var ( - longOIDs = false - lsFilesCmd = &cobra.Command{ - Use: "ls-files", - Run: lsFilesCommand, - } + longOIDs = false ) func lsFilesCommand(cmd *cobra.Command, args []string) { @@ -57,6 +53,13 @@ func lsFilesMarker(p *lfs.WrappedPointer) string { } func init() { - lsFilesCmd.Flags().BoolVarP(&longOIDs, "long", "l", false, "") - RootCmd.AddCommand(lsFilesCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "ls-files", + Run: lsFilesCommand, + } + + cmd.Flags().BoolVarP(&longOIDs, "long", "l", false, "") + return cmd + }) } diff --git a/commands/command_pointer.go b/commands/command_pointer.go index b7c35fd9..1601eac0 100644 --- a/commands/command_pointer.go +++ b/commands/command_pointer.go @@ -18,10 +18,6 @@ var ( pointerFile string pointerCompare string pointerStdin bool - pointerCmd = &cobra.Command{ - Use: "pointer", - Run: pointerCommand, - } ) func pointerCommand(cmd *cobra.Command, args []string) { @@ -133,9 +129,15 @@ func gitHashObject(by []byte) string { } func init() { - flags := pointerCmd.Flags() - flags.StringVarP(&pointerFile, "file", "f", "", "Path to a local file to generate the pointer from.") - flags.StringVarP(&pointerCompare, "pointer", "p", "", "Path to a local file containing a pointer built by another Git LFS implementation.") - flags.BoolVarP(&pointerStdin, "stdin", "", false, "Read a pointer built by another Git LFS implementation through STDIN.") - RootCmd.AddCommand(pointerCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "pointer", + Run: pointerCommand, + } + + cmd.Flags().StringVarP(&pointerFile, "file", "f", "", "Path to a local file to generate the pointer from.") + cmd.Flags().StringVarP(&pointerCompare, "pointer", "p", "", "Path to a local file containing a pointer built by another Git LFS implementation.") + cmd.Flags().BoolVarP(&pointerStdin, "stdin", "", false, "Read a pointer built by another Git LFS implementation through STDIN.") + return cmd + }) } diff --git a/commands/command_pre_push.go b/commands/command_pre_push.go index b231a09c..fafb96c8 100644 --- a/commands/command_pre_push.go +++ b/commands/command_pre_push.go @@ -11,10 +11,6 @@ import ( ) var ( - prePushCmd = &cobra.Command{ - Use: "pre-push", - Run: prePushCommand, - } prePushDryRun = false prePushDeleteBranch = strings.Repeat("0", 40) ) @@ -100,6 +96,13 @@ func decodeRefs(input string) (string, string) { } func init() { - prePushCmd.Flags().BoolVarP(&prePushDryRun, "dry-run", "d", false, "Do everything except actually send the updates") - RootCmd.AddCommand(prePushCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "pre-push", + Run: prePushCommand, + } + + cmd.Flags().BoolVarP(&prePushDryRun, "dry-run", "d", false, "Do everything except actually send the updates") + return cmd + }) } diff --git a/commands/command_prune.go b/commands/command_prune.go index e9443a61..58b403be 100644 --- a/commands/command_prune.go +++ b/commands/command_prune.go @@ -18,11 +18,6 @@ import ( ) var ( - pruneCmd = &cobra.Command{ - Use: "prune", - Short: "Deletes old LFS files from the local store", - Run: pruneCommand, - } pruneDryRunArg bool pruneVerboseArg bool pruneVerifyArg bool @@ -479,9 +474,17 @@ func pruneTaskGetReachableObjects(outObjectSet *tools.StringSet, errorChan chan } func init() { - pruneCmd.Flags().BoolVarP(&pruneDryRunArg, "dry-run", "d", false, "Don't delete anything, just report") - pruneCmd.Flags().BoolVarP(&pruneVerboseArg, "verbose", "v", false, "Print full details of what is/would be deleted") - pruneCmd.Flags().BoolVarP(&pruneVerifyArg, "verify-remote", "c", false, "Verify that remote has LFS files before deleting") - pruneCmd.Flags().BoolVar(&pruneDoNotVerifyArg, "no-verify-remote", false, "Override lfs.pruneverifyremotealways and don't verify") - RootCmd.AddCommand(pruneCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "prune", + Short: "Deletes old LFS files from the local store", + Run: pruneCommand, + } + + cmd.Flags().BoolVarP(&pruneDryRunArg, "dry-run", "d", false, "Don't delete anything, just report") + cmd.Flags().BoolVarP(&pruneVerboseArg, "verbose", "v", false, "Print full details of what is/would be deleted") + cmd.Flags().BoolVarP(&pruneVerifyArg, "verify-remote", "c", false, "Verify that remote has LFS files before deleting") + cmd.Flags().BoolVar(&pruneDoNotVerifyArg, "no-verify-remote", false, "Override lfs.pruneverifyremotealways and don't verify") + return cmd + }) } diff --git a/commands/command_pull.go b/commands/command_pull.go index c839d8b5..036686d3 100644 --- a/commands/command_pull.go +++ b/commands/command_pull.go @@ -7,13 +7,6 @@ import ( "github.com/spf13/cobra" ) -var ( - pullCmd = &cobra.Command{ - Use: "pull", - Run: pullCommand, - } -) - func pullCommand(cmd *cobra.Command, args []string) { requireInRepo() @@ -50,7 +43,14 @@ func pull(includePaths, excludePaths []string) { } func init() { - pullCmd.Flags().StringVarP(&includeArg, "include", "I", "", "Include a list of paths") - pullCmd.Flags().StringVarP(&excludeArg, "exclude", "X", "", "Exclude a list of paths") - RootCmd.AddCommand(pullCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "pull", + Run: pullCommand, + } + + cmd.Flags().StringVarP(&includeArg, "include", "I", "", "Include a list of paths") + cmd.Flags().StringVarP(&excludeArg, "exclude", "X", "", "Exclude a list of paths") + return cmd + }) } diff --git a/commands/command_push.go b/commands/command_push.go index 41d6a276..0754385d 100644 --- a/commands/command_push.go +++ b/commands/command_push.go @@ -11,10 +11,6 @@ import ( ) var ( - pushCmd = &cobra.Command{ - Use: "push", - Run: pushCommand, - } pushDryRun = false pushObjectIDs = false pushAll = false @@ -165,10 +161,16 @@ func pushCommand(cmd *cobra.Command, args []string) { } func init() { - pushCmd.Flags().BoolVarP(&pushDryRun, "dry-run", "d", false, "Do everything except actually send the updates") - pushCmd.Flags().BoolVarP(&useStdin, "stdin", "s", false, "Take refs on stdin (for pre-push hook)") - pushCmd.Flags().BoolVarP(&pushObjectIDs, "object-id", "o", false, "Push LFS object ID(s)") - pushCmd.Flags().BoolVarP(&pushAll, "all", "a", false, "Push all objects for the current ref to the remote.") + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "push", + Run: pushCommand, + } - RootCmd.AddCommand(pushCmd) + cmd.Flags().BoolVarP(&pushDryRun, "dry-run", "d", false, "Do everything except actually send the updates") + cmd.Flags().BoolVarP(&useStdin, "stdin", "s", false, "Take refs on stdin (for pre-push hook)") + cmd.Flags().BoolVarP(&pushObjectIDs, "object-id", "o", false, "Push LFS object ID(s)") + cmd.Flags().BoolVarP(&pushAll, "all", "a", false, "Push all objects for the current ref to the remote.") + return cmd + }) } diff --git a/commands/command_smudge.go b/commands/command_smudge.go index 79042aec..f6410549 100644 --- a/commands/command_smudge.go +++ b/commands/command_smudge.go @@ -15,10 +15,6 @@ import ( var ( smudgeInfo = false smudgeSkip = false - smudgeCmd = &cobra.Command{ - Use: "smudge", - Run: smudgeCommand, - } ) func smudgeCommand(cmd *cobra.Command, args []string) { @@ -99,8 +95,14 @@ func smudgeFilename(args []string, err error) string { } func init() { - // update man page - smudgeCmd.Flags().BoolVarP(&smudgeInfo, "info", "i", false, "") - smudgeCmd.Flags().BoolVarP(&smudgeSkip, "skip", "s", false, "") - RootCmd.AddCommand(smudgeCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "smudge", + Run: smudgeCommand, + } + + cmd.Flags().BoolVarP(&smudgeInfo, "info", "i", false, "") + cmd.Flags().BoolVarP(&smudgeSkip, "skip", "s", false, "") + return cmd + }) } diff --git a/commands/command_status.go b/commands/command_status.go index a262dc10..563becbf 100644 --- a/commands/command_status.go +++ b/commands/command_status.go @@ -9,10 +9,6 @@ import ( ) var ( - statusCmd = &cobra.Command{ - Use: "status", - Run: statusCommand, - } porcelain = false ) @@ -101,6 +97,13 @@ func humanizeBytes(bytes int64) string { } func init() { - statusCmd.Flags().BoolVarP(&porcelain, "porcelain", "p", false, "Give the output in an easy-to-parse format for scripts.") - RootCmd.AddCommand(statusCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "status", + Run: statusCommand, + } + + cmd.Flags().BoolVarP(&porcelain, "porcelain", "p", false, "Give the output in an easy-to-parse format for scripts.") + return cmd + }) } diff --git a/commands/command_track.go b/commands/command_track.go index 3d0eeee1..f6df1923 100644 --- a/commands/command_track.go +++ b/commands/command_track.go @@ -21,11 +21,6 @@ var ( ".git", ".lfs", } - trackCmd = &cobra.Command{ - Use: "track", - Run: trackCommand, - } - trackVerboseLoggingFlag bool trackDryRunFlag bool ) @@ -234,8 +229,14 @@ func blocklistItem(name string) string { } func init() { - trackCmd.Flags().BoolVarP(&trackVerboseLoggingFlag, "verbose", "v", false, "log which files are being tracked and modified") - trackCmd.Flags().BoolVarP(&trackDryRunFlag, "dry-run", "d", false, "preview results of running `git lfs track`") + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "track", + Run: trackCommand, + } - RootCmd.AddCommand(trackCmd) + cmd.Flags().BoolVarP(&trackVerboseLoggingFlag, "verbose", "v", false, "log which files are being tracked and modified") + cmd.Flags().BoolVarP(&trackDryRunFlag, "dry-run", "d", false, "preview results of running `git lfs track`") + return cmd + }) } diff --git a/commands/command_uninit.go b/commands/command_uninit.go index 08ee27e6..db294e82 100644 --- a/commands/command_uninit.go +++ b/commands/command_uninit.go @@ -9,31 +9,29 @@ import ( // TODO: Remove for Git LFS v2.0 https://github.com/github/git-lfs/issues/839 -var ( - // uninitCmd removes any configuration and hooks set by Git LFS. - uninitCmd = &cobra.Command{ - Use: "uninit", - Run: uninitCommand, - } - - // uninitHooksCmd removes any hooks created by Git LFS. - uninitHooksCmd = &cobra.Command{ - Use: "hooks", - Run: uninitHooksCommand, - } -) - +// uninitCmd removes any configuration and hooks set by Git LFS. func uninitCommand(cmd *cobra.Command, args []string) { fmt.Fprintf(os.Stderr, "WARNING: 'git lfs uninit' is deprecated. Use 'git lfs uninstall' now.\n") uninstallCommand(cmd, args) } +// uninitHooksCmd removes any hooks created by Git LFS. func uninitHooksCommand(cmd *cobra.Command, args []string) { fmt.Fprintf(os.Stderr, "WARNING: 'git lfs uninit' is deprecated. Use 'git lfs uninstall' now.\n") uninstallHooksCommand(cmd, args) } func init() { - uninitCmd.AddCommand(uninitHooksCmd) - RootCmd.AddCommand(uninitCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "uninit", + Run: uninitCommand, + } + + cmd.AddCommand(&cobra.Command{ + Use: "hooks", + Run: uninitHooksCommand, + }) + return cmd + }) } diff --git a/commands/command_uninstall.go b/commands/command_uninstall.go index 026bb99c..51e7960a 100644 --- a/commands/command_uninstall.go +++ b/commands/command_uninstall.go @@ -5,20 +5,7 @@ import ( "github.com/spf13/cobra" ) -var ( - // uninstallCmd removes any configuration and hooks set by Git LFS. - uninstallCmd = &cobra.Command{ - Use: "uninstall", - Run: uninstallCommand, - } - - // uninstallHooksCmd removes any hooks created by Git LFS. - uninstallHooksCmd = &cobra.Command{ - Use: "hooks", - Run: uninstallHooksCommand, - } -) - +// uninstallCmd removes any configuration and hooks set by Git LFS. func uninstallCommand(cmd *cobra.Command, args []string) { if err := lfs.UninstallFilters(); err != nil { Error(err.Error()) @@ -31,6 +18,7 @@ func uninstallCommand(cmd *cobra.Command, args []string) { } } +// uninstallHooksCmd removes any hooks created by Git LFS. func uninstallHooksCommand(cmd *cobra.Command, args []string) { if err := lfs.UninstallHooks(); err != nil { Error(err.Error()) @@ -40,6 +28,16 @@ func uninstallHooksCommand(cmd *cobra.Command, args []string) { } func init() { - uninstallCmd.AddCommand(uninstallHooksCmd) - RootCmd.AddCommand(uninstallCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "uninstall", + Run: uninstallCommand, + } + + cmd.AddCommand(&cobra.Command{ + Use: "hooks", + Run: uninstallHooksCommand, + }) + return cmd + }) } diff --git a/commands/command_unlock.go b/commands/command_unlock.go index f14fb252..c2936ae7 100644 --- a/commands/command_unlock.go +++ b/commands/command_unlock.go @@ -16,10 +16,6 @@ var ( errLockAmbiguous = errors.New("lfs: multiple locks found; ambiguous") unlockCmdFlags unlockFlags - unlockCmd = &cobra.Command{ - Use: "unlock", - Run: unlockCommand, - } ) // unlockFlags holds the flags given to the `git lfs unlock` command @@ -97,12 +93,19 @@ func lockIdFromPath(path string) (string, error) { } func init() { - unlockCmd.Flags().StringVarP(&lockRemote, "remote", "r", cfg.CurrentRemote, lockRemoteHelp) + RegisterSubcommand(func() *cobra.Command { + if !isCommandEnabled(cfg, "locks") { + return nil + } - unlockCmd.Flags().StringVarP(&unlockCmdFlags.Id, "id", "i", "", "unlock a lock by its ID") - unlockCmd.Flags().BoolVarP(&unlockCmdFlags.Force, "force", "f", false, "forcibly break another user's lock(s)") + cmd := &cobra.Command{ + Use: "unlock", + Run: unlockCommand, + } - if isCommandEnabled(cfg, "locks") { - RootCmd.AddCommand(unlockCmd) - } + cmd.Flags().StringVarP(&lockRemote, "remote", "r", cfg.CurrentRemote, lockRemoteHelp) + cmd.Flags().StringVarP(&unlockCmdFlags.Id, "id", "i", "", "unlock a lock by its ID") + cmd.Flags().BoolVarP(&unlockCmdFlags.Force, "force", "f", false, "forcibly break another user's lock(s)") + return cmd + }) } diff --git a/commands/command_untrack.go b/commands/command_untrack.go index bd4127bc..cdc82aee 100644 --- a/commands/command_untrack.go +++ b/commands/command_untrack.go @@ -11,13 +11,6 @@ import ( "github.com/spf13/cobra" ) -var ( - untrackCmd = &cobra.Command{ - Use: "untrack", - Run: untrackCommand, - } -) - // untrackCommand takes a list of paths as an argument, and removes each path from the // default attributes file (.gitattributes), if it exists. func untrackCommand(cmd *cobra.Command, args []string) { @@ -82,5 +75,10 @@ func removePath(path string, args []string) bool { } func init() { - RootCmd.AddCommand(untrackCmd) + RegisterSubcommand(func() *cobra.Command { + return &cobra.Command{ + Use: "untrack", + Run: untrackCommand, + } + }) } diff --git a/commands/command_update.go b/commands/command_update.go index f31d451c..8a683260 100644 --- a/commands/command_update.go +++ b/commands/command_update.go @@ -9,11 +9,6 @@ import ( ) var ( - updateCmd = &cobra.Command{ - Use: "update", - Run: updateCommand, - } - updateForce = false updateManual = false ) @@ -59,7 +54,13 @@ func updateCommand(cmd *cobra.Command, args []string) { } func init() { - updateCmd.Flags().BoolVarP(&updateForce, "force", "f", false, "Overwrite existing hooks.") - updateCmd.Flags().BoolVarP(&updateManual, "manual", "m", false, "Print instructions for manual install.") - RootCmd.AddCommand(updateCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "update", + Run: updateCommand, + } + cmd.Flags().BoolVarP(&updateForce, "force", "f", false, "Overwrite existing hooks.") + cmd.Flags().BoolVarP(&updateManual, "manual", "m", false, "Print instructions for manual install.") + return cmd + }) } diff --git a/commands/command_version.go b/commands/command_version.go index 3f584d5b..180d3133 100644 --- a/commands/command_version.go +++ b/commands/command_version.go @@ -7,11 +7,6 @@ import ( var ( lovesComics bool - - versionCmd = &cobra.Command{ - Use: "version", - Run: versionCommand, - } ) func versionCommand(cmd *cobra.Command, args []string) { @@ -23,6 +18,13 @@ func versionCommand(cmd *cobra.Command, args []string) { } func init() { - versionCmd.Flags().BoolVarP(&lovesComics, "comics", "c", false, "easter egg") - RootCmd.AddCommand(versionCmd) + RegisterSubcommand(func() *cobra.Command { + cmd := &cobra.Command{ + Use: "version", + Run: versionCommand, + } + + cmd.Flags().BoolVarP(&lovesComics, "comics", "c", false, "easter egg") + return cmd + }) } diff --git a/commands/commands.go b/commands/commands.go index 07c1973c..0be679a0 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -9,6 +9,7 @@ import ( "os/exec" "path/filepath" "strings" + "sync" "time" "github.com/github/git-lfs/api" @@ -18,6 +19,7 @@ import ( "github.com/github/git-lfs/httputil" "github.com/github/git-lfs/lfs" "github.com/github/git-lfs/tools" + "github.com/github/git-lfs/transfer" "github.com/spf13/cobra" ) @@ -29,23 +31,53 @@ var ( // various command implementations. API = api.NewClient(nil) - Debugging = false - ErrorBuffer = &bytes.Buffer{} - ErrorWriter = io.MultiWriter(os.Stderr, ErrorBuffer) - OutputWriter = io.MultiWriter(os.Stdout, ErrorBuffer) - RootCmd = &cobra.Command{ + Debugging = false + ErrorBuffer = &bytes.Buffer{} + ErrorWriter = io.MultiWriter(os.Stderr, ErrorBuffer) + OutputWriter = io.MultiWriter(os.Stdout, ErrorBuffer) + ManPages = make(map[string]string, 20) + cfg *config.Configuration + transfermanifest *transfer.Manifest + subcommandFuncs []func() *cobra.Command + subcommandMu sync.Mutex + + includeArg string + excludeArg string +) + +func Run() { + cfg = config.Config + transfermanifest = transfer.NewManifest() + transfer.ConfigureManifest(transfermanifest, cfg) + + root := &cobra.Command{ Use: "git-lfs", Run: func(cmd *cobra.Command, args []string) { versionCommand(cmd, args) cmd.Usage() }, } - ManPages = make(map[string]string, 20) - cfg = config.Config - includeArg string - excludeArg string -) + // Set up help/usage funcs based on manpage text + root.SetHelpFunc(help) + root.SetHelpTemplate("{{.UsageString}}") + root.SetUsageFunc(usage) + + for _, f := range subcommandFuncs { + if cmd := f(); cmd != nil { + root.AddCommand(cmd) + } + } + + root.Execute() + httputil.LogHttpStats(cfg) +} + +func RegisterSubcommand(fn func() *cobra.Command) { + subcommandMu.Lock() + subcommandFuncs = append(subcommandFuncs, fn) + subcommandMu.Unlock() +} // Error prints a formatted message to Stderr. It also gets printed to the // panic log if one is created for this command. @@ -108,11 +140,6 @@ func Panic(err error, format string, args ...interface{}) { os.Exit(2) } -func Run() { - RootCmd.Execute() - httputil.LogHttpStats(cfg) -} - func Cleanup() { if err := lfs.ClearTempObjects(); err != nil { fmt.Fprintf(os.Stderr, "Error clearing old temp files: %s\n", err) @@ -287,8 +314,4 @@ func isCommandEnabled(cfg *config.Configuration, cmd string) bool { func init() { log.SetOutput(ErrorWriter) - // Set up help/usage funcs based on manpage text - RootCmd.SetHelpFunc(help) - RootCmd.SetHelpTemplate("{{.UsageString}}") - RootCmd.SetUsageFunc(usage) } From 6a8e9d3f8ec5989d31087adc218ec207a3048c20 Mon Sep 17 00:00:00 2001 From: risk danger olson Date: Wed, 10 Aug 2016 09:37:58 -0600 Subject: [PATCH 02/12] teach lfs.Environ() to accept config and manifest values, instead of pulling from global vars --- commands/command_env.go | 2 +- commands/commands.go | 2 +- lfs/lfs.go | 44 +++++++++++++++++++++-------------------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/commands/command_env.go b/commands/command_env.go index 2107861b..94e90cf6 100644 --- a/commands/command_env.go +++ b/commands/command_env.go @@ -35,7 +35,7 @@ func envCommand(cmd *cobra.Command, args []string) { } } - for _, env := range lfs.Environ() { + for _, env := range lfs.Environ(cfg, transfermanifest) { Print(env) } diff --git a/commands/commands.go b/commands/commands.go index 0be679a0..c9aac3da 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -252,7 +252,7 @@ func logPanicToWriter(w io.Writer, loggedError error) { fmt.Fprintln(w, "\nENV:") // log the environment - for _, env := range lfs.Environ() { + for _, env := range lfs.Environ(cfg, transfermanifest) { fmt.Fprintln(w, env) } } diff --git a/lfs/lfs.go b/lfs/lfs.go index e02919cd..6f0b0524 100644 --- a/lfs/lfs.go +++ b/lfs/lfs.go @@ -67,15 +67,17 @@ func ObjectExistsOfSize(oid string, size int64) bool { return tools.FileExistsOfSize(path, size) } -func Environ() []string { - manifest := transfer.ConfigureManifest(transfer.NewManifest(), config.Config) +func Environ(cfg *config.Configuration, manifest *transfer.Manifest) []string { osEnviron := os.Environ() env := make([]string, 0, len(osEnviron)+7) + dltransfers := manifest.GetDownloadAdapterNames() sort.Strings(dltransfers) ultransfers := manifest.GetUploadAdapterNames() sort.Strings(ultransfers) + fetchPruneConfig := cfg.FetchPruneConfig() + env = append(env, fmt.Sprintf("LocalWorkingDir=%s", config.LocalWorkingDir), fmt.Sprintf("LocalGitDir=%s", config.LocalGitDir), @@ -83,30 +85,30 @@ func Environ() []string { fmt.Sprintf("LocalMediaDir=%s", LocalMediaDir()), fmt.Sprintf("LocalReferenceDir=%s", config.LocalReferenceDir), fmt.Sprintf("TempDir=%s", TempDir()), - fmt.Sprintf("ConcurrentTransfers=%d", config.Config.ConcurrentTransfers()), - fmt.Sprintf("TusTransfers=%v", config.Config.TusTransfersAllowed()), - fmt.Sprintf("BasicTransfersOnly=%v", config.Config.BasicTransfersOnly()), - fmt.Sprintf("BatchTransfer=%v", config.Config.BatchTransfer()), - fmt.Sprintf("SkipDownloadErrors=%v", config.Config.SkipDownloadErrors()), - fmt.Sprintf("FetchRecentAlways=%v", config.Config.FetchPruneConfig().FetchRecentAlways), - fmt.Sprintf("FetchRecentRefsDays=%d", config.Config.FetchPruneConfig().FetchRecentRefsDays), - fmt.Sprintf("FetchRecentCommitsDays=%d", config.Config.FetchPruneConfig().FetchRecentCommitsDays), - fmt.Sprintf("FetchRecentRefsIncludeRemotes=%v", config.Config.FetchPruneConfig().FetchRecentRefsIncludeRemotes), - fmt.Sprintf("PruneOffsetDays=%d", config.Config.FetchPruneConfig().PruneOffsetDays), - fmt.Sprintf("PruneVerifyRemoteAlways=%v", config.Config.FetchPruneConfig().PruneVerifyRemoteAlways), - fmt.Sprintf("PruneRemoteName=%s", config.Config.FetchPruneConfig().PruneRemoteName), - fmt.Sprintf("AccessDownload=%s", config.Config.Access("download")), - fmt.Sprintf("AccessUpload=%s", config.Config.Access("upload")), + fmt.Sprintf("ConcurrentTransfers=%d", cfg.ConcurrentTransfers()), + fmt.Sprintf("TusTransfers=%v", cfg.TusTransfersAllowed()), + fmt.Sprintf("BasicTransfersOnly=%v", cfg.BasicTransfersOnly()), + fmt.Sprintf("BatchTransfer=%v", cfg.BatchTransfer()), + 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("AccessDownload=%s", cfg.Access("download")), + fmt.Sprintf("AccessUpload=%s", cfg.Access("upload")), fmt.Sprintf("DownloadTransfers=%s", strings.Join(dltransfers, ",")), fmt.Sprintf("UploadTransfers=%s", strings.Join(ultransfers, ",")), ) - if len(config.Config.FetchExcludePaths()) > 0 { - env = append(env, fmt.Sprintf("FetchExclude=%s", strings.Join(config.Config.FetchExcludePaths(), ", "))) + if len(cfg.FetchExcludePaths()) > 0 { + env = append(env, fmt.Sprintf("FetchExclude=%s", strings.Join(cfg.FetchExcludePaths(), ", "))) } - if len(config.Config.FetchIncludePaths()) > 0 { - env = append(env, fmt.Sprintf("FetchInclude=%s", strings.Join(config.Config.FetchIncludePaths(), ", "))) + if len(cfg.FetchIncludePaths()) > 0 { + env = append(env, fmt.Sprintf("FetchInclude=%s", strings.Join(cfg.FetchIncludePaths(), ", "))) } - for _, ext := range config.Config.Extensions() { + for _, ext := range cfg.Extensions() { env = append(env, fmt.Sprintf("Extension[%d]=%s", ext.Priority, ext.Name)) } From d3c57fc51bc8690fe945930e127cb9165415d12e Mon Sep 17 00:00:00 2001 From: risk danger olson Date: Wed, 10 Aug 2016 09:42:40 -0600 Subject: [PATCH 03/12] use the global *transfer.Manifest setup in commands.Run() --- commands/command_checkout.go | 5 +---- commands/command_smudge.go | 4 +--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/commands/command_checkout.go b/commands/command_checkout.go index d0b45345..bc9cf2a7 100644 --- a/commands/command_checkout.go +++ b/commands/command_checkout.go @@ -11,7 +11,6 @@ import ( "github.com/github/git-lfs/git" "github.com/github/git-lfs/lfs" "github.com/github/git-lfs/progress" - "github.com/github/git-lfs/transfer" "github.com/rubyist/tracerx" "github.com/spf13/cobra" ) @@ -166,8 +165,6 @@ func checkoutWithChan(in <-chan *lfs.WrappedPointer) { // As files come in, write them to the wd and update the index - manifest := transfer.ConfigureManifest(transfer.NewManifest(), cfg) - for pointer := range in { // Check the content - either missing or still this pointer (not exist is ok) @@ -190,7 +187,7 @@ func checkoutWithChan(in <-chan *lfs.WrappedPointer) { repopathchan <- pointer.Name cwdfilepath := <-cwdpathchan - err = lfs.PointerSmudgeToFile(cwdfilepath, pointer.Pointer, false, manifest, nil) + err = lfs.PointerSmudgeToFile(cwdfilepath, pointer.Pointer, false, transfermanifest, nil) if err != nil { if errutil.IsDownloadDeclinedError(err) { // acceptable error, data not local (fetch not run or include/exclude) diff --git a/commands/command_smudge.go b/commands/command_smudge.go index f6410549..c4e03c7f 100644 --- a/commands/command_smudge.go +++ b/commands/command_smudge.go @@ -8,7 +8,6 @@ import ( "github.com/github/git-lfs/errutil" "github.com/github/git-lfs/lfs" - "github.com/github/git-lfs/transfer" "github.com/spf13/cobra" ) @@ -64,8 +63,7 @@ func smudgeCommand(cmd *cobra.Command, args []string) { download = false } - manifest := transfer.ConfigureManifest(transfer.NewManifest(), cfg) - err = ptr.Smudge(os.Stdout, filename, download, manifest, cb) + err = ptr.Smudge(os.Stdout, filename, download, transfermanifest, cb) if file != nil { file.Close() } From 844a1f479ea78b802ba22bc5c541a4c776bd9acb Mon Sep 17 00:00:00 2001 From: risk danger olson Date: Wed, 10 Aug 2016 10:08:08 -0600 Subject: [PATCH 04/12] remove global *transfer.Manifest from commands pkg only needed in a few commands --- commands/command_checkout.go | 4 +++- commands/command_env.go | 2 +- commands/command_smudge.go | 2 +- commands/commands.go | 27 +++++++++++++++------------ 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/commands/command_checkout.go b/commands/command_checkout.go index bc9cf2a7..1e82d7c7 100644 --- a/commands/command_checkout.go +++ b/commands/command_checkout.go @@ -165,6 +165,8 @@ func checkoutWithChan(in <-chan *lfs.WrappedPointer) { // As files come in, write them to the wd and update the index + manifest := TransferManifest() + for pointer := range in { // Check the content - either missing or still this pointer (not exist is ok) @@ -187,7 +189,7 @@ func checkoutWithChan(in <-chan *lfs.WrappedPointer) { repopathchan <- pointer.Name cwdfilepath := <-cwdpathchan - err = lfs.PointerSmudgeToFile(cwdfilepath, pointer.Pointer, false, transfermanifest, nil) + err = lfs.PointerSmudgeToFile(cwdfilepath, pointer.Pointer, false, manifest, nil) if err != nil { if errutil.IsDownloadDeclinedError(err) { // acceptable error, data not local (fetch not run or include/exclude) diff --git a/commands/command_env.go b/commands/command_env.go index 94e90cf6..804beaef 100644 --- a/commands/command_env.go +++ b/commands/command_env.go @@ -35,7 +35,7 @@ func envCommand(cmd *cobra.Command, args []string) { } } - for _, env := range lfs.Environ(cfg, transfermanifest) { + for _, env := range lfs.Environ(cfg, TransferManifest()) { Print(env) } diff --git a/commands/command_smudge.go b/commands/command_smudge.go index c4e03c7f..9afac558 100644 --- a/commands/command_smudge.go +++ b/commands/command_smudge.go @@ -63,7 +63,7 @@ func smudgeCommand(cmd *cobra.Command, args []string) { download = false } - err = ptr.Smudge(os.Stdout, filename, download, transfermanifest, cb) + err = ptr.Smudge(os.Stdout, filename, download, TransferManifest(), cb) if file != nil { file.Close() } diff --git a/commands/commands.go b/commands/commands.go index c9aac3da..7dc94830 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -31,15 +31,14 @@ var ( // various command implementations. API = api.NewClient(nil) - Debugging = false - ErrorBuffer = &bytes.Buffer{} - ErrorWriter = io.MultiWriter(os.Stderr, ErrorBuffer) - OutputWriter = io.MultiWriter(os.Stdout, ErrorBuffer) - ManPages = make(map[string]string, 20) - cfg *config.Configuration - transfermanifest *transfer.Manifest - subcommandFuncs []func() *cobra.Command - subcommandMu sync.Mutex + Debugging = false + ErrorBuffer = &bytes.Buffer{} + ErrorWriter = io.MultiWriter(os.Stderr, ErrorBuffer) + OutputWriter = io.MultiWriter(os.Stdout, ErrorBuffer) + ManPages = make(map[string]string, 20) + cfg *config.Configuration + subcommandFuncs []func() *cobra.Command + subcommandMu sync.Mutex includeArg string excludeArg string @@ -47,8 +46,6 @@ var ( func Run() { cfg = config.Config - transfermanifest = transfer.NewManifest() - transfer.ConfigureManifest(transfermanifest, cfg) root := &cobra.Command{ Use: "git-lfs", @@ -79,6 +76,12 @@ func RegisterSubcommand(fn func() *cobra.Command) { subcommandMu.Unlock() } +// TransferManifest builds a transfer.Manifest from the commands package global +// cfg var. +func TransferManifest() *transfer.Manifest { + return transfer.ConfigureManifest(transfer.NewManifest(), cfg) +} + // Error prints a formatted message to Stderr. It also gets printed to the // panic log if one is created for this command. func Error(format string, args ...interface{}) { @@ -252,7 +255,7 @@ func logPanicToWriter(w io.Writer, loggedError error) { fmt.Fprintln(w, "\nENV:") // log the environment - for _, env := range lfs.Environ(cfg, transfermanifest) { + for _, env := range lfs.Environ(cfg, TransferManifest()) { fmt.Fprintln(w, env) } } From fc23a3725db99f752bce0ec9a36d4a329c993c93 Mon Sep 17 00:00:00 2001 From: Taylor Blau Date: Wed, 10 Aug 2016 13:00:32 -0600 Subject: [PATCH 05/12] config/config: remove SetConfig and ResetConfig methods --- config/config.go | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/config/config.go b/config/config.go index ecc87b7c..32d81696 100644 --- a/config/config.go +++ b/config/config.go @@ -492,30 +492,3 @@ func (c *Configuration) loadGitConfig() bool { return true } - -// XXX(taylor): remove mutability -func (c *Configuration) SetConfig(key, value string) { - if c.loadGitConfig() { - c.loading.Lock() - c.origConfig = make(map[string]string) - for k, v := range c.gitConfig { - c.origConfig[k] = v - } - c.loading.Unlock() - } - - c.gitConfig[key] = value -} - -// XXX(taylor): remove mutability -func (c *Configuration) ResetConfig() { - c.loading.Lock() - c.gitConfig = make(map[string]string) - if gf, ok := c.Git.Fetcher.(*GitFetcher); ok { - gf.vals = c.gitConfig - } - for k, v := range c.origConfig { - c.gitConfig[k] = v - } - c.loading.Unlock() -} From 31544d078d6d9ccf07ab0081edba62dd87a944c1 Mon Sep 17 00:00:00 2001 From: Taylor Blau Date: Wed, 10 Aug 2016 13:01:22 -0600 Subject: [PATCH 06/12] config/config: remove `origConfig` field --- config/config.go | 1 - 1 file changed, 1 deletion(-) diff --git a/config/config.go b/config/config.go index 32d81696..247963cc 100644 --- a/config/config.go +++ b/config/config.go @@ -68,7 +68,6 @@ type Configuration struct { IsLoggingStats bool loading sync.Mutex // guards initialization of gitConfig and remotes - origConfig map[string]string remotes []string extensions map[string]Extension manualEndpoint *Endpoint From c1170b75f28d47d8b11178759003c39bf526f343 Mon Sep 17 00:00:00 2001 From: Taylor Blau Date: Fri, 12 Aug 2016 13:21:25 -0600 Subject: [PATCH 07/12] transfer/custom: encode "event" as lowercase --- transfer/custom.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transfer/custom.go b/transfer/custom.go index 210dc2c6..1e4949c8 100644 --- a/transfer/custom.go +++ b/transfer/custom.go @@ -63,7 +63,7 @@ type customAdapterWorkerContext struct { } type customAdapterInitRequest struct { - Event string `json:"Event"` + Event string `json:"event"` Operation string `json:"operation"` Concurrent bool `json:"concurrent"` ConcurrentTransfers int `json:"concurrenttransfers"` From 71fbb41f531e3395c12e1a9c436240a63ef43e8e Mon Sep 17 00:00:00 2001 From: risk danger olson Date: Fri, 12 Aug 2016 15:20:46 -0600 Subject: [PATCH 08/12] add support for url.*.insteadof in git config --- config/config.go | 20 ++++++++++++++++++++ config/endpoint.go | 7 +++++++ test/test-config.sh | 19 +++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/config/config.go b/config/config.go index 247963cc..489d8719 100644 --- a/config/config.go +++ b/config/config.go @@ -72,6 +72,8 @@ type Configuration struct { extensions map[string]Extension manualEndpoint *Endpoint parsedNetrc netrcfinder + urlAliases map[string]string + urlAliasMu sync.Mutex } func New() *Configuration { @@ -449,6 +451,24 @@ func (c *Configuration) AllGitConfig() map[string]string { return c.gitConfig } +func (c *Configuration) UrlAliases() map[string]string { + c.urlAliasMu.Lock() + defer c.urlAliasMu.Unlock() + + if c.urlAliases == nil { + c.urlAliases = make(map[string]string) + prefix := "url." + suffix := ".insteadof" + for gitkey, gitval := range c.AllGitConfig() { + if strings.HasPrefix(gitkey, prefix) && strings.HasSuffix(gitkey, suffix) { + c.urlAliases[gitval] = gitkey[len(prefix) : len(gitkey)-len(suffix)] + } + } + } + + return c.urlAliases +} + func (c *Configuration) FetchPruneConfig() FetchPruneConfig { f := &FetchPruneConfig{ FetchRecentRefsDays: 7, diff --git a/config/endpoint.go b/config/endpoint.go index b76392ee..1475f17a 100644 --- a/config/endpoint.go +++ b/config/endpoint.go @@ -48,6 +48,13 @@ func NewEndpointFromCloneURLWithConfig(url string, c *Configuration) Endpoint { // NewEndpointWithConfig initializes a new Endpoint for a given URL. func NewEndpointWithConfig(rawurl string, c *Configuration) Endpoint { + for alias, replacement := range c.UrlAliases() { + if !strings.HasPrefix(rawurl, alias) { + continue + } + rawurl = replacement + rawurl[len(alias):] + } + u, err := url.Parse(rawurl) if err != nil { return Endpoint{Url: EndpointUrlUnknown} diff --git a/test/test-config.sh b/test/test-config.sh index 66b91831..e314d3b7 100755 --- a/test/test-config.sh +++ b/test/test-config.sh @@ -149,3 +149,22 @@ begin_test "extension config (with gitconfig)" [ "$expected2" = "$(git lfs ext)" ] ) end_test + +begin_test "url alias config" +( + set -e + + mkdir url-alias + cd url-alias + + git init + git config url."http://actual-url/".insteadOf alias: + git config lfs.url alias:rest + git lfs env | tee env.log + grep "Endpoint=http://actual-url/rest (auth=none)" env.log + + git config lfs.url badalias:rest + git lfs env | tee env.log + grep "Endpoint=badalias:rest (auth=none)" env.log +) +end_test From 26f72f50cfbdc3a2293281aecfb372fe4521e482 Mon Sep 17 00:00:00 2001 From: risk danger olson Date: Fri, 12 Aug 2016 15:33:54 -0600 Subject: [PATCH 09/12] handle cases where someone has multiple url.*.insteadof keys with the same alias value --- config/config.go | 25 +++++++++++++++++++++++++ config/endpoint.go | 8 +------- test/test-config.sh | 5 +++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/config/config.go b/config/config.go index 489d8719..e7c923c3 100644 --- a/config/config.go +++ b/config/config.go @@ -5,6 +5,7 @@ package config import ( "errors" "fmt" + "os" "reflect" "strconv" "strings" @@ -469,6 +470,30 @@ func (c *Configuration) UrlAliases() map[string]string { return c.urlAliases } +// ReplaceUrlAlias returns a url with a prefix from a `url.*.insteadof` git +// config setting. If multiple aliases match, use the longest one. +// See https://git-scm.com/docs/git-config for Git's docs. +func (c *Configuration) ReplaceUrlAlias(rawurl string) string { + var longestalias string + for alias, _ := range c.UrlAliases() { + if !strings.HasPrefix(rawurl, alias) { + continue + } + + if longestalias < alias { + longestalias = alias + } else if longestalias == alias { + fmt.Fprintf(os.Stderr, "WARNING: Multiple 'url.*.insteadof' keys with the same alias: %q", alias) + } + } + + if len(longestalias) > 0 { + return c.UrlAliases()[longestalias] + rawurl[len(longestalias):] + } + + return rawurl +} + func (c *Configuration) FetchPruneConfig() FetchPruneConfig { f := &FetchPruneConfig{ FetchRecentRefsDays: 7, diff --git a/config/endpoint.go b/config/endpoint.go index 1475f17a..8ef73948 100644 --- a/config/endpoint.go +++ b/config/endpoint.go @@ -48,13 +48,7 @@ func NewEndpointFromCloneURLWithConfig(url string, c *Configuration) Endpoint { // NewEndpointWithConfig initializes a new Endpoint for a given URL. func NewEndpointWithConfig(rawurl string, c *Configuration) Endpoint { - for alias, replacement := range c.UrlAliases() { - if !strings.HasPrefix(rawurl, alias) { - continue - } - rawurl = replacement + rawurl[len(alias):] - } - + rawurl = c.ReplaceUrlAlias(rawurl) u, err := url.Parse(rawurl) if err != nil { return Endpoint{Url: EndpointUrlUnknown} diff --git a/test/test-config.sh b/test/test-config.sh index e314d3b7..83e74b37 100755 --- a/test/test-config.sh +++ b/test/test-config.sh @@ -150,6 +150,7 @@ begin_test "extension config (with gitconfig)" ) end_test +# https://git-scm.com/docs/git-config begin_test "url alias config" ( set -e @@ -158,11 +159,15 @@ begin_test "url alias config" cd url-alias git init + + # When more than one insteadOf strings match a given URL, the longest match is used. + git config url."http://wrong-url/".insteadOf alias git config url."http://actual-url/".insteadOf alias: git config lfs.url alias:rest git lfs env | tee env.log grep "Endpoint=http://actual-url/rest (auth=none)" env.log + # Any URL that starts with this value will be rewritten to start, instead, with git config lfs.url badalias:rest git lfs env | tee env.log grep "Endpoint=badalias:rest (auth=none)" env.log From db0da8aa3b23fb3f2ae258674ca90d3245df7b73 Mon Sep 17 00:00:00 2001 From: risk danger olson Date: Fri, 12 Aug 2016 15:41:07 -0600 Subject: [PATCH 10/12] no need to export UrlAliases() --- config/config.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/config/config.go b/config/config.go index e7c923c3..9855bcd1 100644 --- a/config/config.go +++ b/config/config.go @@ -73,7 +73,7 @@ type Configuration struct { extensions map[string]Extension manualEndpoint *Endpoint parsedNetrc netrcfinder - urlAliases map[string]string + urlAliasesMap map[string]string urlAliasMu sync.Mutex } @@ -452,22 +452,22 @@ func (c *Configuration) AllGitConfig() map[string]string { return c.gitConfig } -func (c *Configuration) UrlAliases() map[string]string { +func (c *Configuration) urlAliases() map[string]string { c.urlAliasMu.Lock() defer c.urlAliasMu.Unlock() - if c.urlAliases == nil { - c.urlAliases = make(map[string]string) + if c.urlAliasesMap == nil { + c.urlAliasesMap = make(map[string]string) prefix := "url." suffix := ".insteadof" for gitkey, gitval := range c.AllGitConfig() { if strings.HasPrefix(gitkey, prefix) && strings.HasSuffix(gitkey, suffix) { - c.urlAliases[gitval] = gitkey[len(prefix) : len(gitkey)-len(suffix)] + c.urlAliasesMap[gitval] = gitkey[len(prefix) : len(gitkey)-len(suffix)] } } } - return c.urlAliases + return c.urlAliasesMap } // ReplaceUrlAlias returns a url with a prefix from a `url.*.insteadof` git @@ -475,7 +475,8 @@ func (c *Configuration) UrlAliases() map[string]string { // See https://git-scm.com/docs/git-config for Git's docs. func (c *Configuration) ReplaceUrlAlias(rawurl string) string { var longestalias string - for alias, _ := range c.UrlAliases() { + aliases := c.urlAliases() + for alias, _ := range aliases { if !strings.HasPrefix(rawurl, alias) { continue } @@ -488,7 +489,7 @@ func (c *Configuration) ReplaceUrlAlias(rawurl string) string { } if len(longestalias) > 0 { - return c.UrlAliases()[longestalias] + rawurl[len(longestalias):] + return aliases[longestalias] + rawurl[len(longestalias):] } return rawurl From 8cff656434676d9084cfa3303ad9af8952ebe73a Mon Sep 17 00:00:00 2001 From: risk danger olson Date: Fri, 12 Aug 2016 16:30:43 -0600 Subject: [PATCH 11/12] put the insteadof warning in the correct place --- config/config.go | 5 +++-- test/test-config.sh | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/config/config.go b/config/config.go index 9855bcd1..c2b7357c 100644 --- a/config/config.go +++ b/config/config.go @@ -462,6 +462,9 @@ func (c *Configuration) urlAliases() map[string]string { suffix := ".insteadof" for gitkey, gitval := range c.AllGitConfig() { if strings.HasPrefix(gitkey, prefix) && strings.HasSuffix(gitkey, suffix) { + if _, ok := c.urlAliasesMap[gitval]; ok { + fmt.Fprintf(os.Stderr, "WARNING: Multiple 'url.*.insteadof' keys with the same alias: %q\n", gitval) + } c.urlAliasesMap[gitval] = gitkey[len(prefix) : len(gitkey)-len(suffix)] } } @@ -483,8 +486,6 @@ func (c *Configuration) ReplaceUrlAlias(rawurl string) string { if longestalias < alias { longestalias = alias - } else if longestalias == alias { - fmt.Fprintf(os.Stderr, "WARNING: Multiple 'url.*.insteadof' keys with the same alias: %q", alias) } } diff --git a/test/test-config.sh b/test/test-config.sh index 83e74b37..1af848a8 100755 --- a/test/test-config.sh +++ b/test/test-config.sh @@ -150,7 +150,6 @@ begin_test "extension config (with gitconfig)" ) end_test -# https://git-scm.com/docs/git-config begin_test "url alias config" ( set -e @@ -166,8 +165,38 @@ begin_test "url alias config" git config lfs.url alias:rest git lfs env | tee env.log grep "Endpoint=http://actual-url/rest (auth=none)" env.log +) +end_test - # Any URL that starts with this value will be rewritten to start, instead, with +begin_test "ambiguous url alias" +( + set -e + + mkdir url-alias-ambiguous + cd url-alias-ambiguous + + git init + + git config url."http://actual-url/".insteadOf alias: + git config url."http://dupe-url".insteadOf alias: + git config lfs.url alias:rest + git config -l | grep url + + git lfs env 2>&1 | tee env2.log + grep "WARNING: Multiple 'url.*.insteadof'" env2.log +) +end_test + +begin_test "url alias must be prefix" +( + set -e + + mkdir url-alias-bad + cd url-alias-bad + + git init + + git config url."http://actual-url/".insteadOf alias: git config lfs.url badalias:rest git lfs env | tee env.log grep "Endpoint=badalias:rest (auth=none)" env.log From b546ba4db320f38a531b21e95074b56013cf4104 Mon Sep 17 00:00:00 2001 From: Taylor Blau Date: Mon, 15 Aug 2016 10:38:02 -0600 Subject: [PATCH 12/12] ROADMAP: link `config-next` to tracking issue --- ROADMAP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ROADMAP.md b/ROADMAP.md index bce8734e..1f36a01d 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -11,7 +11,7 @@ Git LFS. If you have an idea for a new feature, open an issue for discussion. | :soon: | `authenticated` property on urls | [#960](https://github.com/github/git-lfs/issues/960) | | :soon: | Add ref information to upload request | [#969](https://github.com/github/git-lfs/issues/969) | | :soon: | Accept raw remote URLs as valid | [#1085](https://github.com/github/git-lfs/issues/1085) | -| :construction: | `config` refactoring | | +| :construction: | `config` refactoring | [#1425](https://github.com/github/git-lfs/issues/1425) | | :soon: | Socks proxy support | [#1424](https://github.com/github/git-lfs/issues/1424) | | :no_entry_sign: | Not following 301 redirect | [#1129](https://github.com/github/git-lfs/issues/1129) | | | add all lfs.\* git config keys to git lfs env output | |