1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2026-06-20 01:19:23 +02:00

Don't use go-git to parse remotes

It only takes a few lines of code to parse remotes on our end from the output of
`git config --get-regexp`.
This commit is contained in:
Stefan Haller
2026-03-26 10:06:01 +01:00
parent d864edb0c3
commit 23f973496f
2 changed files with 36 additions and 23 deletions
+1 -1
View File
@@ -142,7 +142,7 @@ func NewGitCommandAux(
commitFileLoader := git_commands.NewCommitFileLoader(cmn, cmd) commitFileLoader := git_commands.NewCommitFileLoader(cmn, cmd)
commitLoader := git_commands.NewCommitLoader(cmn, cmd, statusCommands.WorkingTreeState, gitCommon) commitLoader := git_commands.NewCommitLoader(cmn, cmd, statusCommands.WorkingTreeState, gitCommon)
reflogCommitLoader := git_commands.NewReflogCommitLoader(cmn, cmd) 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) worktreeLoader := git_commands.NewWorktreeLoader(gitCommon)
stashLoader := git_commands.NewStashLoader(cmn, cmd) stashLoader := git_commands.NewStashLoader(cmn, cmd)
tagLoader := git_commands.NewTagLoader(cmn, cmd) tagLoader := git_commands.NewTagLoader(cmn, cmd)
+35 -22
View File
@@ -2,33 +2,29 @@ package git_commands
import ( import (
"fmt" "fmt"
"maps"
"slices" "slices"
"strings" "strings"
"sync" "sync"
gogit "github.com/jesseduffield/go-git/v5"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/common" "github.com/jesseduffield/lazygit/pkg/common"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
) )
type RemoteLoader struct { type RemoteLoader struct {
*common.Common *common.Common
cmd oscommands.ICmdObjBuilder cmd oscommands.ICmdObjBuilder
getGoGitRemotes func() ([]*gogit.Remote, error)
} }
func NewRemoteLoader( func NewRemoteLoader(
common *common.Common, common *common.Common,
cmd oscommands.ICmdObjBuilder, cmd oscommands.ICmdObjBuilder,
getGoGitRemotes func() ([]*gogit.Remote, error),
) *RemoteLoader { ) *RemoteLoader {
return &RemoteLoader{ return &RemoteLoader{
Common: common, Common: common,
cmd: cmd, cmd: cmd,
getGoGitRemotes: getGoGitRemotes,
} }
} }
@@ -44,10 +40,7 @@ func (self *RemoteLoader) GetRemotes() ([]*models.Remote, error) {
remoteBranchesByRemoteName, remoteBranchesErr = self.getRemoteBranchesByRemoteName() remoteBranchesByRemoteName, remoteBranchesErr = self.getRemoteBranchesByRemoteName()
}) })
goGitRemotes, err := self.getGoGitRemotes() remotes := self.getRemotesFromConfig()
if err != nil {
return nil, err
}
wg.Wait() wg.Wait()
@@ -55,16 +48,9 @@ func (self *RemoteLoader) GetRemotes() ([]*models.Remote, error) {
return nil, remoteBranchesErr return nil, remoteBranchesErr
} }
remotes := lo.Map(goGitRemotes, func(goGitRemote *gogit.Remote, _ int) *models.Remote { for _, remote := range remotes {
remoteName := goGitRemote.Config().Name remote.Branches = remoteBranchesByRemoteName[remote.Name]
branches := remoteBranchesByRemoteName[remoteName] }
return &models.Remote{
Name: goGitRemote.Config().Name,
Urls: goGitRemote.Config().URLs,
Branches: branches,
}
})
// now lets sort our remotes by name alphabetically // now lets sort our remotes by name alphabetically
slices.SortFunc(remotes, func(a, b *models.Remote) int { slices.SortFunc(remotes, func(a, b *models.Remote) int {
@@ -81,6 +67,33 @@ func (self *RemoteLoader) GetRemotes() ([]*models.Remote, error) {
return remotes, nil 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.<name>.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) { func (self *RemoteLoader) getRemoteBranchesByRemoteName() (map[string][]*models.RemoteBranch, error) {
remoteBranchesByRemoteName := make(map[string][]*models.RemoteBranch) remoteBranchesByRemoteName := make(map[string][]*models.RemoteBranch)