diff --git a/pkg/commands/git.go b/pkg/commands/git.go index 90514cbd6..a5666cfc1 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -142,7 +142,7 @@ func NewGitCommandAux( commitFileLoader := git_commands.NewCommitFileLoader(cmn, cmd) commitLoader := git_commands.NewCommitLoader(cmn, cmd, statusCommands.WorkingTreeState, gitCommon) reflogCommitLoader := git_commands.NewReflogCommitLoader(cmn, cmd) - remoteLoader := git_commands.NewRemoteLoader(cmn, cmd, repo.Remotes) + remoteLoader := git_commands.NewRemoteLoader(cmn, cmd) worktreeLoader := git_commands.NewWorktreeLoader(gitCommon) stashLoader := git_commands.NewStashLoader(cmn, cmd) tagLoader := git_commands.NewTagLoader(cmn, cmd) diff --git a/pkg/commands/git_commands/remote_loader.go b/pkg/commands/git_commands/remote_loader.go index 2e632def4..164ab0016 100644 --- a/pkg/commands/git_commands/remote_loader.go +++ b/pkg/commands/git_commands/remote_loader.go @@ -2,33 +2,29 @@ package git_commands import ( "fmt" + "maps" "slices" "strings" "sync" - gogit "github.com/jesseduffield/go-git/v5" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/common" "github.com/jesseduffield/lazygit/pkg/utils" - "github.com/samber/lo" ) type RemoteLoader struct { *common.Common - cmd oscommands.ICmdObjBuilder - getGoGitRemotes func() ([]*gogit.Remote, error) + cmd oscommands.ICmdObjBuilder } func NewRemoteLoader( common *common.Common, cmd oscommands.ICmdObjBuilder, - getGoGitRemotes func() ([]*gogit.Remote, error), ) *RemoteLoader { return &RemoteLoader{ - Common: common, - cmd: cmd, - getGoGitRemotes: getGoGitRemotes, + Common: common, + cmd: cmd, } } @@ -44,10 +40,7 @@ func (self *RemoteLoader) GetRemotes() ([]*models.Remote, error) { remoteBranchesByRemoteName, remoteBranchesErr = self.getRemoteBranchesByRemoteName() }) - goGitRemotes, err := self.getGoGitRemotes() - if err != nil { - return nil, err - } + remotes := self.getRemotesFromConfig() wg.Wait() @@ -55,16 +48,9 @@ func (self *RemoteLoader) GetRemotes() ([]*models.Remote, error) { return nil, remoteBranchesErr } - remotes := lo.Map(goGitRemotes, func(goGitRemote *gogit.Remote, _ int) *models.Remote { - remoteName := goGitRemote.Config().Name - branches := remoteBranchesByRemoteName[remoteName] - - return &models.Remote{ - Name: goGitRemote.Config().Name, - Urls: goGitRemote.Config().URLs, - Branches: branches, - } - }) + for _, remote := range remotes { + remote.Branches = remoteBranchesByRemoteName[remote.Name] + } // now lets sort our remotes by name alphabetically slices.SortFunc(remotes, func(a, b *models.Remote) int { @@ -81,6 +67,33 @@ func (self *RemoteLoader) GetRemotes() ([]*models.Remote, error) { return remotes, nil } +func (self *RemoteLoader) getRemotesFromConfig() []*models.Remote { + cmdArgs := NewGitCmd("config"). + Arg("--local", "--get-regexp", `^remote\.[^.]+\.url$`).ToArgv() + output, err := self.cmd.New(cmdArgs).DontLog().RunWithOutput() + if err != nil { + // exit code 1 means no matching keys (no remotes configured) + return nil + } + + remotesByName := make(map[string]*models.Remote) + + for _, line := range strings.Split(output, "\n") { + key, url, found := strings.Cut(strings.TrimSpace(line), " ") + if !found { + continue + } + // key is "remote..url"; strip prefix and suffix to get the name + remoteName := strings.TrimSuffix(strings.TrimPrefix(key, "remote."), ".url") + if _, ok := remotesByName[remoteName]; !ok { + remotesByName[remoteName] = &models.Remote{Name: remoteName} + } + remotesByName[remoteName].Urls = append(remotesByName[remoteName].Urls, url) + } + + return slices.Collect(maps.Values(remotesByName)) +} + func (self *RemoteLoader) getRemoteBranchesByRemoteName() (map[string][]*models.RemoteBranch, error) { remoteBranchesByRemoteName := make(map[string][]*models.RemoteBranch)