mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-12 12:55:47 +02:00
Factor out CommitLoader.mainBranches into its own class, and store it in Model
This commit is contained in:
parent
2ae1bea20a
commit
aba0290e51
7 changed files with 120 additions and 69 deletions
|
@ -35,11 +35,6 @@ type CommitLoader struct {
|
||||||
readFile func(filename string) ([]byte, error)
|
readFile func(filename string) ([]byte, error)
|
||||||
walkFiles func(root string, fn filepath.WalkFunc) error
|
walkFiles func(root string, fn filepath.WalkFunc) error
|
||||||
dotGitDir string
|
dotGitDir string
|
||||||
// List of main branches that exist in the repo.
|
|
||||||
// We use these to obtain the merge base of the branch.
|
|
||||||
// When nil, we're yet to obtain the list of existing main branches.
|
|
||||||
// When an empty slice, we've obtained the list and it's empty.
|
|
||||||
mainBranches []string
|
|
||||||
*GitCommon
|
*GitCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +51,6 @@ func NewCommitLoader(
|
||||||
getRebaseMode: getRebaseMode,
|
getRebaseMode: getRebaseMode,
|
||||||
readFile: os.ReadFile,
|
readFile: os.ReadFile,
|
||||||
walkFiles: filepath.Walk,
|
walkFiles: filepath.Walk,
|
||||||
mainBranches: nil,
|
|
||||||
GitCommon: gitCommon,
|
GitCommon: gitCommon,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,6 +66,7 @@ type GetCommitsOptions struct {
|
||||||
All bool
|
All bool
|
||||||
// If non-empty, show divergence from this ref (left-right log)
|
// If non-empty, show divergence from this ref (left-right log)
|
||||||
RefToShowDivergenceFrom string
|
RefToShowDivergenceFrom string
|
||||||
|
ExistingMainBranches *ExistingMainBranches
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCommits obtains the commits of the current branch
|
// GetCommits obtains the commits of the current branch
|
||||||
|
@ -108,9 +103,9 @@ func (self *CommitLoader) GetCommits(opts GetCommitsOptions) ([]*models.Commit,
|
||||||
go utils.Safe(func() {
|
go utils.Safe(func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
ancestor = self.getMergeBase(opts.RefName)
|
ancestor = self.getMergeBase(opts.RefName, opts.ExistingMainBranches)
|
||||||
if opts.RefToShowDivergenceFrom != "" {
|
if opts.RefToShowDivergenceFrom != "" {
|
||||||
remoteAncestor = self.getMergeBase(opts.RefToShowDivergenceFrom)
|
remoteAncestor = self.getMergeBase(opts.RefToShowDivergenceFrom, opts.ExistingMainBranches)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -471,12 +466,9 @@ func setCommitMergedStatuses(ancestor string, commits []*models.Commit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CommitLoader) getMergeBase(refName string) string {
|
func (self *CommitLoader) getMergeBase(refName string, existingMainBranches *ExistingMainBranches) string {
|
||||||
if self.mainBranches == nil {
|
mainBranches := existingMainBranches.Get()
|
||||||
self.mainBranches = self.getExistingMainBranches()
|
if len(mainBranches) == 0 {
|
||||||
}
|
|
||||||
|
|
||||||
if len(self.mainBranches) == 0 {
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,69 +476,18 @@ func (self *CommitLoader) getMergeBase(refName string) string {
|
||||||
// return the base commit for the closest one.
|
// return the base commit for the closest one.
|
||||||
|
|
||||||
output, err := self.cmd.New(
|
output, err := self.cmd.New(
|
||||||
NewGitCmd("merge-base").Arg(refName).Arg(self.mainBranches...).
|
NewGitCmd("merge-base").Arg(refName).Arg(mainBranches...).
|
||||||
ToArgv(),
|
ToArgv(),
|
||||||
).DontLog().RunWithOutput()
|
).DontLog().RunWithOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If there's an error, it must be because one of the main branches that
|
// If there's an error, it must be because one of the main branches that
|
||||||
// used to exist when we called getExistingMainBranches() was deleted
|
// used to exist when we called getExistingMainBranches() was deleted
|
||||||
// meanwhile. To fix this for next time, throw away our cache.
|
// meanwhile. To fix this for next time, throw away our cache.
|
||||||
self.mainBranches = nil
|
existingMainBranches.Clear()
|
||||||
}
|
}
|
||||||
return ignoringWarnings(output)
|
return ignoringWarnings(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CommitLoader) getExistingMainBranches() []string {
|
|
||||||
var existingBranches []string
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
mainBranches := self.UserConfig.Git.MainBranches
|
|
||||||
existingBranches = make([]string, len(mainBranches))
|
|
||||||
|
|
||||||
for i, branchName := range mainBranches {
|
|
||||||
wg.Add(1)
|
|
||||||
go utils.Safe(func() {
|
|
||||||
defer wg.Done()
|
|
||||||
|
|
||||||
// Try to determine upstream of local main branch
|
|
||||||
if ref, err := self.cmd.New(
|
|
||||||
NewGitCmd("rev-parse").Arg("--symbolic-full-name", branchName+"@{u}").ToArgv(),
|
|
||||||
).DontLog().RunWithOutput(); err == nil {
|
|
||||||
existingBranches[i] = strings.TrimSpace(ref)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this failed, a local branch for this main branch doesn't exist or it
|
|
||||||
// has no upstream configured. Try looking for one in the "origin" remote.
|
|
||||||
ref := "refs/remotes/origin/" + branchName
|
|
||||||
if err := self.cmd.New(
|
|
||||||
NewGitCmd("rev-parse").Arg("--verify", "--quiet", ref).ToArgv(),
|
|
||||||
).DontLog().Run(); err == nil {
|
|
||||||
existingBranches[i] = ref
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this failed as well, try if we have the main branch as a local
|
|
||||||
// branch. This covers the case where somebody is using git locally
|
|
||||||
// for something, but never pushing anywhere.
|
|
||||||
ref = "refs/heads/" + branchName
|
|
||||||
if err := self.cmd.New(
|
|
||||||
NewGitCmd("rev-parse").Arg("--verify", "--quiet", ref).ToArgv(),
|
|
||||||
).DontLog().Run(); err == nil {
|
|
||||||
existingBranches[i] = ref
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
existingBranches = lo.Filter(existingBranches, func(branch string, _ int) bool {
|
|
||||||
return branch != ""
|
|
||||||
})
|
|
||||||
|
|
||||||
return existingBranches
|
|
||||||
}
|
|
||||||
|
|
||||||
func ignoringWarnings(commandOutput string) string {
|
func ignoringWarnings(commandOutput string) string {
|
||||||
trimmedOutput := strings.TrimSpace(commandOutput)
|
trimmedOutput := strings.TrimSpace(commandOutput)
|
||||||
split := strings.Split(trimmedOutput, "\n")
|
split := strings.Split(trimmedOutput, "\n")
|
||||||
|
|
|
@ -307,10 +307,11 @@ func TestGetCommits(t *testing.T) {
|
||||||
common := utils.NewDummyCommon()
|
common := utils.NewDummyCommon()
|
||||||
common.AppState = &config.AppState{}
|
common.AppState = &config.AppState{}
|
||||||
common.AppState.GitLogOrder = scenario.logOrder
|
common.AppState.GitLogOrder = scenario.logOrder
|
||||||
|
cmd := oscommands.NewDummyCmdObjBuilder(scenario.runner)
|
||||||
|
|
||||||
builder := &CommitLoader{
|
builder := &CommitLoader{
|
||||||
Common: common,
|
Common: common,
|
||||||
cmd: oscommands.NewDummyCmdObjBuilder(scenario.runner),
|
cmd: cmd,
|
||||||
getRebaseMode: func() (enums.RebaseMode, error) { return scenario.rebaseMode, nil },
|
getRebaseMode: func() (enums.RebaseMode, error) { return scenario.rebaseMode, nil },
|
||||||
dotGitDir: ".git",
|
dotGitDir: ".git",
|
||||||
readFile: func(filename string) ([]byte, error) {
|
readFile: func(filename string) ([]byte, error) {
|
||||||
|
@ -322,7 +323,9 @@ func TestGetCommits(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
common.UserConfig.Git.MainBranches = scenario.mainBranches
|
common.UserConfig.Git.MainBranches = scenario.mainBranches
|
||||||
commits, err := builder.GetCommits(scenario.opts)
|
opts := scenario.opts
|
||||||
|
opts.ExistingMainBranches = NewExistingMainBranches(scenario.mainBranches, cmd)
|
||||||
|
commits, err := builder.GetCommits(opts)
|
||||||
|
|
||||||
assert.Equal(t, scenario.expectedCommits, commits)
|
assert.Equal(t, scenario.expectedCommits, commits)
|
||||||
assert.Equal(t, scenario.expectedError, err)
|
assert.Equal(t, scenario.expectedError, err)
|
||||||
|
|
101
pkg/commands/git_commands/existing_main_branches.go
Normal file
101
pkg/commands/git_commands/existing_main_branches.go
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
package git_commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
|
"github.com/samber/lo"
|
||||||
|
"github.com/sasha-s/go-deadlock"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ExistingMainBranches struct {
|
||||||
|
configuredMainBranches []string
|
||||||
|
existingBranches []string
|
||||||
|
|
||||||
|
cmd oscommands.ICmdObjBuilder
|
||||||
|
mutex *deadlock.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewExistingMainBranches(
|
||||||
|
configuredMainBranches []string,
|
||||||
|
cmd oscommands.ICmdObjBuilder,
|
||||||
|
) *ExistingMainBranches {
|
||||||
|
return &ExistingMainBranches{
|
||||||
|
configuredMainBranches: configuredMainBranches,
|
||||||
|
existingBranches: nil,
|
||||||
|
cmd: cmd,
|
||||||
|
mutex: &deadlock.Mutex{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *ExistingMainBranches) Get() []string {
|
||||||
|
self.mutex.Lock()
|
||||||
|
defer self.mutex.Unlock()
|
||||||
|
|
||||||
|
if self.existingBranches == nil {
|
||||||
|
self.existingBranches = self.determineMainBranches()
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.existingBranches
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *ExistingMainBranches) Clear() {
|
||||||
|
self.mutex.Lock()
|
||||||
|
defer self.mutex.Unlock()
|
||||||
|
|
||||||
|
self.existingBranches = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *ExistingMainBranches) determineMainBranches() []string {
|
||||||
|
var existingBranches []string
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
existingBranches = make([]string, len(self.configuredMainBranches))
|
||||||
|
|
||||||
|
for i, branchName := range self.configuredMainBranches {
|
||||||
|
wg.Add(1)
|
||||||
|
i := i
|
||||||
|
branchName := branchName
|
||||||
|
go utils.Safe(func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
// Try to determine upstream of local main branch
|
||||||
|
if ref, err := self.cmd.New(
|
||||||
|
NewGitCmd("rev-parse").Arg("--symbolic-full-name", branchName+"@{u}").ToArgv(),
|
||||||
|
).DontLog().RunWithOutput(); err == nil {
|
||||||
|
existingBranches[i] = strings.TrimSpace(ref)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this failed, a local branch for this main branch doesn't exist or it
|
||||||
|
// has no upstream configured. Try looking for one in the "origin" remote.
|
||||||
|
ref := "refs/remotes/origin/" + branchName
|
||||||
|
if err := self.cmd.New(
|
||||||
|
NewGitCmd("rev-parse").Arg("--verify", "--quiet", ref).ToArgv(),
|
||||||
|
).DontLog().Run(); err == nil {
|
||||||
|
existingBranches[i] = ref
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this failed as well, try if we have the main branch as a local
|
||||||
|
// branch. This covers the case where somebody is using git locally
|
||||||
|
// for something, but never pushing anywhere.
|
||||||
|
ref = "refs/heads/" + branchName
|
||||||
|
if err := self.cmd.New(
|
||||||
|
NewGitCmd("rev-parse").Arg("--verify", "--quiet", ref).ToArgv(),
|
||||||
|
).DontLog().Run(); err == nil {
|
||||||
|
existingBranches[i] = ref
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
existingBranches = lo.Filter(existingBranches, func(branch string, _ int) bool {
|
||||||
|
return branch != ""
|
||||||
|
})
|
||||||
|
|
||||||
|
return existingBranches
|
||||||
|
}
|
|
@ -326,6 +326,7 @@ func (self *RefreshHelper) refreshCommitsWithLimit() error {
|
||||||
RefName: self.refForLog(),
|
RefName: self.refForLog(),
|
||||||
RefForPushedStatus: checkedOutBranchName,
|
RefForPushedStatus: checkedOutBranchName,
|
||||||
All: self.c.Contexts().LocalCommits.GetShowWholeGitGraph(),
|
All: self.c.Contexts().LocalCommits.GetShowWholeGitGraph(),
|
||||||
|
ExistingMainBranches: self.c.Model().ExistingMainBranches,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -352,6 +353,7 @@ func (self *RefreshHelper) refreshSubCommitsWithLimit() error {
|
||||||
RefName: self.c.Contexts().SubCommits.GetRef().FullRefName(),
|
RefName: self.c.Contexts().SubCommits.GetRef().FullRefName(),
|
||||||
RefToShowDivergenceFrom: self.c.Contexts().SubCommits.GetRefToShowDivergenceFrom(),
|
RefToShowDivergenceFrom: self.c.Contexts().SubCommits.GetRefToShowDivergenceFrom(),
|
||||||
RefForPushedStatus: self.c.Contexts().SubCommits.GetRef().FullRefName(),
|
RefForPushedStatus: self.c.Contexts().SubCommits.GetRef().FullRefName(),
|
||||||
|
ExistingMainBranches: self.c.Model().ExistingMainBranches,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -44,6 +44,7 @@ func (self *SubCommitsHelper) ViewSubCommits(opts ViewSubCommitsOpts) error {
|
||||||
RefName: opts.Ref.FullRefName(),
|
RefName: opts.Ref.FullRefName(),
|
||||||
RefForPushedStatus: opts.Ref.FullRefName(),
|
RefForPushedStatus: opts.Ref.FullRefName(),
|
||||||
RefToShowDivergenceFrom: opts.RefToShowDivergenceFrom,
|
RefToShowDivergenceFrom: opts.RefToShowDivergenceFrom,
|
||||||
|
ExistingMainBranches: self.c.Model().ExistingMainBranches,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -386,6 +386,7 @@ func (gui *Gui) resetState(startArgs appTypes.StartArgs) types.Context {
|
||||||
BisectInfo: git_commands.NewNullBisectInfo(),
|
BisectInfo: git_commands.NewNullBisectInfo(),
|
||||||
FilesTrie: patricia.NewTrie(),
|
FilesTrie: patricia.NewTrie(),
|
||||||
Authors: map[string]*models.Author{},
|
Authors: map[string]*models.Author{},
|
||||||
|
ExistingMainBranches: git_commands.NewExistingMainBranches(gui.UserConfig.Git.MainBranches, gui.os.Cmd),
|
||||||
},
|
},
|
||||||
Modes: &types.Modes{
|
Modes: &types.Modes{
|
||||||
Filtering: filtering.New(startArgs.FilterPath, ""),
|
Filtering: filtering.New(startArgs.FilterPath, ""),
|
||||||
|
|
|
@ -281,6 +281,8 @@ type Model struct {
|
||||||
// we're on a detached head because we're rebasing or bisecting.
|
// we're on a detached head because we're rebasing or bisecting.
|
||||||
CheckedOutBranch string
|
CheckedOutBranch string
|
||||||
|
|
||||||
|
ExistingMainBranches *git_commands.ExistingMainBranches
|
||||||
|
|
||||||
// for displaying suggestions while typing in a file name
|
// for displaying suggestions while typing in a file name
|
||||||
FilesTrie *patricia.Trie
|
FilesTrie *patricia.Trie
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue