1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-07-31 14:24:25 +03:00

refactor controllers

This commit is contained in:
Jesse Duffield
2022-02-06 15:54:26 +11:00
parent b93b8cc00a
commit 722410aded
56 changed files with 1406 additions and 1553 deletions

View File

@ -1,18 +1,5 @@
package gui package gui
import (
"errors"
"fmt"
"strings"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
)
// list panel functions
func (gui *Gui) branchesRenderToMain() error { func (gui *Gui) branchesRenderToMain() error {
var task updateTask var task updateTask
branch := gui.State.Contexts.Branches.GetSelected() branch := gui.State.Contexts.Branches.GetSelected()
@ -31,368 +18,3 @@ func (gui *Gui) branchesRenderToMain() error {
}, },
}) })
} }
// specific functions
func (gui *Gui) handleBranchPress() error {
branch := gui.State.Contexts.Branches.GetSelected()
if branch == nil {
return nil
}
if branch == gui.getCheckedOutBranch() {
return gui.c.ErrorMsg(gui.c.Tr.AlreadyCheckedOutBranch)
}
gui.c.LogAction(gui.c.Tr.Actions.CheckoutBranch)
return gui.helpers.Refs.CheckoutRef(branch.Name, types.CheckoutRefOptions{})
}
func (gui *Gui) handleCreatePullRequestPress() error {
branch := gui.State.Contexts.Branches.GetSelected()
return gui.createPullRequest(branch.Name, "")
}
func (gui *Gui) handleCreatePullRequestMenu() error {
selectedBranch := gui.State.Contexts.Branches.GetSelected()
if selectedBranch == nil {
return nil
}
checkedOutBranch := gui.getCheckedOutBranch()
return gui.createPullRequestMenu(selectedBranch, checkedOutBranch)
}
func (gui *Gui) handleCopyPullRequestURLPress() error {
hostingServiceMgr := gui.getHostingServiceMgr()
branch := gui.State.Contexts.Branches.GetSelected()
branchExistsOnRemote := gui.git.Remote.CheckRemoteBranchExists(branch.Name)
if !branchExistsOnRemote {
return gui.c.Error(errors.New(gui.c.Tr.NoBranchOnRemote))
}
url, err := hostingServiceMgr.GetPullRequestURL(branch.Name, "")
if err != nil {
return gui.c.Error(err)
}
gui.c.LogAction(gui.c.Tr.Actions.CopyPullRequestURL)
if err := gui.os.CopyToClipboard(url); err != nil {
return gui.c.Error(err)
}
gui.c.Toast(gui.c.Tr.PullRequestURLCopiedToClipboard)
return nil
}
func (gui *Gui) handleGitFetch() error {
return gui.c.WithLoaderPanel(gui.c.Tr.FetchWait, func() error {
if err := gui.fetch(); err != nil {
_ = gui.c.Error(err)
}
return gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
})
}
func (gui *Gui) handleForceCheckout() error {
branch := gui.State.Contexts.Branches.GetSelected()
message := gui.c.Tr.SureForceCheckout
title := gui.c.Tr.ForceCheckoutBranch
return gui.c.Ask(types.AskOpts{
Title: title,
Prompt: message,
HandleConfirm: func() error {
gui.c.LogAction(gui.c.Tr.Actions.ForceCheckoutBranch)
if err := gui.git.Branch.Checkout(branch.Name, git_commands.CheckoutOptions{Force: true}); err != nil {
_ = gui.c.Error(err)
}
return gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
},
})
}
func (gui *Gui) handleCheckoutByName() error {
return gui.c.Prompt(types.PromptOpts{
Title: gui.c.Tr.BranchName + ":",
FindSuggestionsFunc: gui.helpers.Suggestions.GetRefsSuggestionsFunc(),
HandleConfirm: func(response string) error {
gui.c.LogAction("Checkout branch")
return gui.helpers.Refs.CheckoutRef(response, types.CheckoutRefOptions{
OnRefNotFound: func(ref string) error {
return gui.c.Ask(types.AskOpts{
Title: gui.c.Tr.BranchNotFoundTitle,
Prompt: fmt.Sprintf("%s %s%s", gui.c.Tr.BranchNotFoundPrompt, ref, "?"),
HandleConfirm: func() error {
return gui.createNewBranchWithName(ref)
},
})
},
})
}},
)
}
func (gui *Gui) getCheckedOutBranch() *models.Branch {
if len(gui.State.Model.Branches) == 0 {
return nil
}
return gui.State.Model.Branches[0]
}
func (gui *Gui) createNewBranchWithName(newBranchName string) error {
branch := gui.State.Contexts.Branches.GetSelected()
if branch == nil {
return nil
}
if err := gui.git.Branch.New(newBranchName, branch.Name); err != nil {
return gui.c.Error(err)
}
gui.State.Contexts.Branches.SetSelectedLineIdx(0)
return gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
}
func (gui *Gui) handleDeleteBranch() error {
return gui.deleteBranch(false)
}
func (gui *Gui) deleteBranch(force bool) error {
selectedBranch := gui.State.Contexts.Branches.GetSelected()
if selectedBranch == nil {
return nil
}
checkedOutBranch := gui.getCheckedOutBranch()
if checkedOutBranch.Name == selectedBranch.Name {
return gui.c.ErrorMsg(gui.c.Tr.CantDeleteCheckOutBranch)
}
return gui.deleteNamedBranch(selectedBranch, force)
}
func (gui *Gui) deleteNamedBranch(selectedBranch *models.Branch, force bool) error {
title := gui.c.Tr.DeleteBranch
var templateStr string
if force {
templateStr = gui.c.Tr.ForceDeleteBranchMessage
} else {
templateStr = gui.c.Tr.DeleteBranchMessage
}
message := utils.ResolvePlaceholderString(
templateStr,
map[string]string{
"selectedBranchName": selectedBranch.Name,
},
)
return gui.c.Ask(types.AskOpts{
Title: title,
Prompt: message,
HandleConfirm: func() error {
gui.c.LogAction(gui.c.Tr.Actions.DeleteBranch)
if err := gui.git.Branch.Delete(selectedBranch.Name, force); err != nil {
errMessage := err.Error()
if !force && strings.Contains(errMessage, "git branch -D ") {
return gui.deleteNamedBranch(selectedBranch, true)
}
return gui.c.ErrorMsg(errMessage)
}
return gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}})
},
})
}
func (gui *Gui) mergeBranchIntoCheckedOutBranch(branchName string) error {
if gui.git.Branch.IsHeadDetached() {
return gui.c.ErrorMsg("Cannot merge branch in detached head state. You might have checked out a commit directly or a remote branch, in which case you should checkout the local branch you want to be on")
}
checkedOutBranchName := gui.getCheckedOutBranch().Name
if checkedOutBranchName == branchName {
return gui.c.ErrorMsg(gui.c.Tr.CantMergeBranchIntoItself)
}
prompt := utils.ResolvePlaceholderString(
gui.c.Tr.ConfirmMerge,
map[string]string{
"checkedOutBranch": checkedOutBranchName,
"selectedBranch": branchName,
},
)
return gui.c.Ask(types.AskOpts{
Title: gui.c.Tr.MergingTitle,
Prompt: prompt,
HandleConfirm: func() error {
gui.c.LogAction(gui.c.Tr.Actions.Merge)
err := gui.git.Branch.Merge(branchName, git_commands.MergeOpts{})
return gui.helpers.Rebase.CheckMergeOrRebase(err)
},
})
}
func (gui *Gui) handleMerge() error {
selectedBranchName := gui.State.Contexts.Branches.GetSelected().Name
return gui.mergeBranchIntoCheckedOutBranch(selectedBranchName)
}
func (gui *Gui) handleRebaseOntoLocalBranch() error {
selectedBranchName := gui.State.Contexts.Branches.GetSelected().Name
return gui.handleRebaseOntoBranch(selectedBranchName)
}
func (gui *Gui) handleRebaseOntoBranch(selectedBranchName string) error {
checkedOutBranch := gui.getCheckedOutBranch().Name
if selectedBranchName == checkedOutBranch {
return gui.c.ErrorMsg(gui.c.Tr.CantRebaseOntoSelf)
}
prompt := utils.ResolvePlaceholderString(
gui.c.Tr.ConfirmRebase,
map[string]string{
"checkedOutBranch": checkedOutBranch,
"selectedBranch": selectedBranchName,
},
)
return gui.c.Ask(types.AskOpts{
Title: gui.c.Tr.RebasingTitle,
Prompt: prompt,
HandleConfirm: func() error {
gui.c.LogAction(gui.c.Tr.Actions.RebaseBranch)
err := gui.git.Rebase.RebaseBranch(selectedBranchName)
return gui.helpers.Rebase.CheckMergeOrRebase(err)
},
})
}
func (gui *Gui) handleFastForward() error {
branch := gui.State.Contexts.Branches.GetSelected()
if branch == nil || !branch.IsRealBranch() {
return nil
}
if !branch.IsTrackingRemote() {
return gui.c.ErrorMsg(gui.c.Tr.FwdNoUpstream)
}
if !branch.RemoteBranchStoredLocally() {
return gui.c.ErrorMsg(gui.c.Tr.FwdNoLocalUpstream)
}
if branch.HasCommitsToPush() {
return gui.c.ErrorMsg(gui.c.Tr.FwdCommitsToPush)
}
action := gui.c.Tr.Actions.FastForwardBranch
message := utils.ResolvePlaceholderString(
gui.c.Tr.Fetching,
map[string]string{
"from": fmt.Sprintf("%s/%s", branch.UpstreamRemote, branch.UpstreamBranch),
"to": branch.Name,
},
)
return gui.c.WithLoaderPanel(message, func() error {
if branch == gui.getCheckedOutBranch() {
gui.c.LogAction(action)
err := gui.git.Sync.Pull(
git_commands.PullOptions{
RemoteName: branch.UpstreamRemote,
BranchName: branch.Name,
FastForwardOnly: true,
},
)
if err != nil {
_ = gui.c.Error(err)
}
return gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
} else {
gui.c.LogAction(action)
err := gui.git.Sync.FastForward(branch.Name, branch.UpstreamRemote, branch.UpstreamBranch)
if err != nil {
_ = gui.c.Error(err)
}
_ = gui.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}})
}
return nil
})
}
func (gui *Gui) handleCreateResetToBranchMenu() error {
branch := gui.State.Contexts.Branches.GetSelected()
if branch == nil {
return nil
}
return gui.helpers.Refs.CreateGitResetMenu(branch.Name)
}
func (gui *Gui) handleRenameBranch() error {
branch := gui.State.Contexts.Branches.GetSelected()
if branch == nil || !branch.IsRealBranch() {
return nil
}
promptForNewName := func() error {
return gui.c.Prompt(types.PromptOpts{
Title: gui.c.Tr.NewBranchNamePrompt + " " + branch.Name + ":",
InitialContent: branch.Name,
HandleConfirm: func(newBranchName string) error {
gui.c.LogAction(gui.c.Tr.Actions.RenameBranch)
if err := gui.git.Branch.Rename(branch.Name, newBranchName); err != nil {
return gui.c.Error(err)
}
// need to find where the branch is now so that we can re-select it. That means we need to refetch the branches synchronously and then find our branch
gui.refreshBranches()
// now that we've got our stuff again we need to find that branch and reselect it.
for i, newBranch := range gui.State.Model.Branches {
if newBranch.Name == newBranchName {
gui.State.Contexts.Branches.SetSelectedLineIdx(i)
if err := gui.State.Contexts.Branches.HandleRender(); err != nil {
return err
}
}
}
return nil
},
})
}
// I could do an explicit check here for whether the branch is tracking a remote branch
// but if we've selected it we'll already know that via Pullables and Pullables.
// Bit of a hack but I'm lazy.
if !branch.IsTrackingRemote() {
return promptForNewName()
}
return gui.c.Ask(types.AskOpts{
Title: gui.c.Tr.LcRenameBranch,
Prompt: gui.c.Tr.RenameBranchWarning,
HandleConfirm: promptForNewName,
})
}
func (gui *Gui) handleEnterBranch() error {
branch := gui.State.Contexts.Branches.GetSelected()
if branch == nil {
return nil
}
return gui.switchToSubCommitsContext(branch.RefName())
}
func (gui *Gui) handleNewBranchOffBranch() error {
selectedBranch := gui.State.Contexts.Branches.GetSelected()
if selectedBranch == nil {
return nil
}
return gui.helpers.Refs.NewBranch(selectedBranch.RefName(), selectedBranch.RefName(), "")
}

View File

@ -85,7 +85,7 @@ func (gui *Gui) handleDiscardOldFileChange() error {
return gui.c.WithWaitingStatus(gui.c.Tr.RebasingStatus, func() error { return gui.c.WithWaitingStatus(gui.c.Tr.RebasingStatus, func() error {
gui.c.LogAction(gui.c.Tr.Actions.DiscardOldFileChange) gui.c.LogAction(gui.c.Tr.Actions.DiscardOldFileChange)
if err := gui.git.Rebase.DiscardOldFileChanges(gui.State.Model.Commits, gui.State.Contexts.BranchCommits.GetSelectedLineIdx(), fileName); err != nil { if err := gui.git.Rebase.DiscardOldFileChanges(gui.State.Model.Commits, gui.State.Contexts.BranchCommits.GetSelectedLineIdx(), fileName); err != nil {
if err := gui.helpers.Rebase.CheckMergeOrRebase(err); err != nil { if err := gui.helpers.MergeAndRebase.CheckMergeOrRebase(err); err != nil {
return err return err
} }
} }
@ -265,7 +265,7 @@ func (gui *Gui) SwitchToCommitFilesContext(opts controllers.SwitchToCommitFilesC
gui.State.Contexts.CommitFiles.SetRefName(opts.RefName) gui.State.Contexts.CommitFiles.SetRefName(opts.RefName)
gui.State.Contexts.CommitFiles.SetCanRebase(opts.CanRebase) gui.State.Contexts.CommitFiles.SetCanRebase(opts.CanRebase)
gui.State.Contexts.CommitFiles.SetParentContext(opts.Context) gui.State.Contexts.CommitFiles.SetParentContext(opts.Context)
gui.State.Contexts.CommitFiles.SetWindowName(opts.WindowName) gui.State.Contexts.CommitFiles.SetWindowName(opts.Context.GetWindowName())
if err := gui.refreshCommitFilesView(); err != nil { if err := gui.refreshCommitFilesView(); err != nil {
return err return err

View File

@ -23,7 +23,7 @@ func NewBranchesContext(
onRenderToMain func(...types.OnFocusOpts) error, onRenderToMain func(...types.OnFocusOpts) error,
onFocusLost func() error, onFocusLost func() error,
c *types.ControllerCommon, c *types.HelperCommon,
) *BranchesContext { ) *BranchesContext {
viewModel := NewBranchesViewModel(getModel) viewModel := NewBranchesViewModel(getModel)

View File

@ -23,7 +23,7 @@ func NewCommitFilesContext(
onRenderToMain func(...types.OnFocusOpts) error, onRenderToMain func(...types.OnFocusOpts) error,
onFocusLost func() error, onFocusLost func() error,
c *types.ControllerCommon, c *types.HelperCommon,
) *CommitFilesContext { ) *CommitFilesContext {
viewModel := filetree.NewCommitFileTreeViewModel(getModel, c.Log, c.UserConfig.Gui.ShowFileTree) viewModel := filetree.NewCommitFileTreeViewModel(getModel, c.Log, c.UserConfig.Gui.ShowFileTree)

View File

@ -10,7 +10,7 @@ import (
type ListContextTrait struct { type ListContextTrait struct {
types.Context types.Context
c *types.ControllerCommon c *types.HelperCommon
list types.IList list types.IList
viewTrait *ViewTrait viewTrait *ViewTrait
getDisplayStrings func(startIdx int, length int) [][]string getDisplayStrings func(startIdx int, length int) [][]string

View File

@ -23,7 +23,7 @@ func NewLocalCommitsContext(
onRenderToMain func(...types.OnFocusOpts) error, onRenderToMain func(...types.OnFocusOpts) error,
onFocusLost func() error, onFocusLost func() error,
c *types.ControllerCommon, c *types.HelperCommon,
) *LocalCommitsContext { ) *LocalCommitsContext {
viewModel := NewLocalCommitsViewModel(getModel) viewModel := NewLocalCommitsViewModel(getModel)
@ -61,8 +61,14 @@ func (self *LocalCommitsContext) GetSelectedItemId() string {
type LocalCommitsViewModel struct { type LocalCommitsViewModel struct {
*traits.ListCursor *traits.ListCursor
getModel func() []*models.Commit
// If this is true we limit the amount of commits we load, for the sake of keeping things fast.
// If the user attempts to scroll past the end of the list, we will load more commits.
limitCommits bool limitCommits bool
getModel func() []*models.Commit
// If this is true we'll use git log --all when fetching the commits.
showWholeGitGraph bool
} }
func NewLocalCommitsViewModel(getModel func() []*models.Commit) *LocalCommitsViewModel { func NewLocalCommitsViewModel(getModel func() []*models.Commit) *LocalCommitsViewModel {
@ -95,3 +101,11 @@ func (self *LocalCommitsViewModel) SetLimitCommits(value bool) {
func (self *LocalCommitsViewModel) GetLimitCommits() bool { func (self *LocalCommitsViewModel) GetLimitCommits() bool {
return self.limitCommits return self.limitCommits
} }
func (self *LocalCommitsViewModel) SetShowWholeGitGraph(value bool) {
self.showWholeGitGraph = value
}
func (self *LocalCommitsViewModel) GetShowWholeGitGraph() bool {
return self.showWholeGitGraph
}

View File

@ -21,7 +21,7 @@ func NewMenuContext(
onRenderToMain func(...types.OnFocusOpts) error, onRenderToMain func(...types.OnFocusOpts) error,
onFocusLost func() error, onFocusLost func() error,
c *types.ControllerCommon, c *types.HelperCommon,
getOptionsMap func() map[string]string, getOptionsMap func() map[string]string,
) *MenuContext { ) *MenuContext {
viewModel := NewMenuViewModel() viewModel := NewMenuViewModel()

View File

@ -23,7 +23,7 @@ func NewReflogCommitsContext(
onRenderToMain func(...types.OnFocusOpts) error, onRenderToMain func(...types.OnFocusOpts) error,
onFocusLost func() error, onFocusLost func() error,
c *types.ControllerCommon, c *types.HelperCommon,
) *ReflogCommitsContext { ) *ReflogCommitsContext {
viewModel := NewReflogCommitsViewModel(getModel) viewModel := NewReflogCommitsViewModel(getModel)

View File

@ -23,7 +23,7 @@ func NewRemoteBranchesContext(
onRenderToMain func(...types.OnFocusOpts) error, onRenderToMain func(...types.OnFocusOpts) error,
onFocusLost func() error, onFocusLost func() error,
c *types.ControllerCommon, c *types.HelperCommon,
) *RemoteBranchesContext { ) *RemoteBranchesContext {
viewModel := NewRemoteBranchesViewModel(getModel) viewModel := NewRemoteBranchesViewModel(getModel)

View File

@ -23,7 +23,7 @@ func NewRemotesContext(
onRenderToMain func(...types.OnFocusOpts) error, onRenderToMain func(...types.OnFocusOpts) error,
onFocusLost func() error, onFocusLost func() error,
c *types.ControllerCommon, c *types.HelperCommon,
) *RemotesContext { ) *RemotesContext {
viewModel := NewRemotesViewModel(getModel) viewModel := NewRemotesViewModel(getModel)

View File

@ -23,7 +23,7 @@ func NewStashContext(
onRenderToMain func(...types.OnFocusOpts) error, onRenderToMain func(...types.OnFocusOpts) error,
onFocusLost func() error, onFocusLost func() error,
c *types.ControllerCommon, c *types.HelperCommon,
) *StashContext { ) *StashContext {
viewModel := NewStashViewModel(getModel) viewModel := NewStashViewModel(getModel)

View File

@ -23,7 +23,7 @@ func NewSubCommitsContext(
onRenderToMain func(...types.OnFocusOpts) error, onRenderToMain func(...types.OnFocusOpts) error,
onFocusLost func() error, onFocusLost func() error,
c *types.ControllerCommon, c *types.HelperCommon,
) *SubCommitsContext { ) *SubCommitsContext {
viewModel := NewSubCommitsViewModel(getModel) viewModel := NewSubCommitsViewModel(getModel)

View File

@ -23,7 +23,7 @@ func NewSubmodulesContext(
onRenderToMain func(...types.OnFocusOpts) error, onRenderToMain func(...types.OnFocusOpts) error,
onFocusLost func() error, onFocusLost func() error,
c *types.ControllerCommon, c *types.HelperCommon,
) *SubmodulesContext { ) *SubmodulesContext {
viewModel := NewSubmodulesViewModel(getModel) viewModel := NewSubmodulesViewModel(getModel)

View File

@ -22,7 +22,7 @@ func NewSuggestionsContext(
onRenderToMain func(...types.OnFocusOpts) error, onRenderToMain func(...types.OnFocusOpts) error,
onFocusLost func() error, onFocusLost func() error,
c *types.ControllerCommon, c *types.HelperCommon,
) *SuggestionsContext { ) *SuggestionsContext {
viewModel := NewSuggestionsViewModel(getModel) viewModel := NewSuggestionsViewModel(getModel)

View File

@ -23,7 +23,7 @@ func NewTagsContext(
onRenderToMain func(...types.OnFocusOpts) error, onRenderToMain func(...types.OnFocusOpts) error,
onFocusLost func() error, onFocusLost func() error,
c *types.ControllerCommon, c *types.HelperCommon,
) *TagsContext { ) *TagsContext {
viewModel := NewTagsViewModel(getModel) viewModel := NewTagsViewModel(getModel)

View File

@ -23,7 +23,7 @@ func NewWorkingTreeContext(
onRenderToMain func(...types.OnFocusOpts) error, onRenderToMain func(...types.OnFocusOpts) error,
onFocusLost func() error, onFocusLost func() error,
c *types.ControllerCommon, c *types.HelperCommon,
) *WorkingTreeContext { ) *WorkingTreeContext {
viewModel := filetree.NewFileTreeViewModel(getModel, c.Log, c.UserConfig.Gui.ShowFileTree) viewModel := filetree.NewFileTreeViewModel(getModel, c.Log, c.UserConfig.Gui.ShowFileTree)

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/context"
@ -13,33 +12,17 @@ import (
type BisectController struct { type BisectController struct {
baseController baseController
*controllerCommon
c *types.ControllerCommon
context *context.LocalCommitsContext
git *commands.GitCommand
bisectHelper *BisectHelper
getCommits func() []*models.Commit
} }
var _ types.IController = &BisectController{} var _ types.IController = &BisectController{}
func NewBisectController( func NewBisectController(
c *types.ControllerCommon, common *controllerCommon,
context *context.LocalCommitsContext,
git *commands.GitCommand,
bisectHelper *BisectHelper,
getCommits func() []*models.Commit,
) *BisectController { ) *BisectController {
return &BisectController{ return &BisectController{
baseController: baseController{}, baseController: baseController{},
c: c, controllerCommon: common,
context: context,
git: git,
bisectHelper: bisectHelper,
getCommits: getCommits,
} }
} }
@ -119,7 +102,7 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c
{ {
DisplayString: self.c.Tr.Bisect.ResetOption, DisplayString: self.c.Tr.Bisect.ResetOption,
OnPress: func() error { OnPress: func() error {
return self.bisectHelper.Reset() return self.helpers.Bisect.Reset()
}, },
}, },
} }
@ -146,7 +129,7 @@ func (self *BisectController) openStartBisectMenu(info *git_commands.BisectInfo,
return self.c.Error(err) return self.c.Error(err)
} }
return self.bisectHelper.PostBisectCommandRefresh() return self.helpers.Bisect.PostBisectCommandRefresh()
}, },
}, },
{ {
@ -161,7 +144,7 @@ func (self *BisectController) openStartBisectMenu(info *git_commands.BisectInfo,
return self.c.Error(err) return self.c.Error(err)
} }
return self.bisectHelper.PostBisectCommandRefresh() return self.helpers.Bisect.PostBisectCommandRefresh()
}, },
}, },
}, },
@ -188,7 +171,7 @@ func (self *BisectController) showBisectCompleteMessage(candidateShas []string)
return self.c.Error(err) return self.c.Error(err)
} }
return self.bisectHelper.PostBisectCommandRefresh() return self.helpers.Bisect.PostBisectCommandRefresh()
}, },
}) })
} }
@ -222,7 +205,7 @@ func (self *BisectController) afterBisectMarkRefresh(selectCurrent bool, waitToR
} else { } else {
selectFn() selectFn()
return self.bisectHelper.PostBisectCommandRefresh() return self.helpers.Bisect.PostBisectCommandRefresh()
} }
} }
@ -230,10 +213,10 @@ func (self *BisectController) selectCurrentBisectCommit() {
info := self.git.Bisect.GetInfo() info := self.git.Bisect.GetInfo()
if info.GetCurrentSha() != "" { if info.GetCurrentSha() != "" {
// find index of commit with that sha, move cursor to that. // find index of commit with that sha, move cursor to that.
for i, commit := range self.getCommits() { for i, commit := range self.model.Commits {
if commit.Sha == info.GetCurrentSha() { if commit.Sha == info.GetCurrentSha() {
self.context.SetSelectedLineIdx(i) self.context().SetSelectedLineIdx(i)
_ = self.context.HandleFocus() _ = self.context().HandleFocus()
break break
} }
} }
@ -242,7 +225,7 @@ func (self *BisectController) selectCurrentBisectCommit() {
func (self *BisectController) checkSelected(callback func(*models.Commit) error) func() error { func (self *BisectController) checkSelected(callback func(*models.Commit) error) func() error {
return func() error { return func() error {
commit := self.context.GetSelected() commit := self.context().GetSelected()
if commit == nil { if commit == nil {
return nil return nil
} }
@ -252,5 +235,9 @@ func (self *BisectController) checkSelected(callback func(*models.Commit) error)
} }
func (self *BisectController) Context() types.Context { func (self *BisectController) Context() types.Context {
return self.context return self.context()
}
func (self *BisectController) context() *context.LocalCommitsContext {
return self.contexts.BranchCommits
} }

View File

@ -0,0 +1,475 @@
package controllers
import (
"errors"
"fmt"
"strings"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
)
type BranchesController struct {
baseController
*controllerCommon
}
var _ types.IController = &BranchesController{}
func NewBranchesController(
common *controllerCommon,
) *BranchesController {
return &BranchesController{
baseController: baseController{},
controllerCommon: common,
}
}
func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
return []*types.Binding{
{
ViewName: "branches",
Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)},
Key: opts.GetKey(opts.Config.Universal.Select),
Handler: self.handleBranchPress,
Description: self.c.Tr.LcCheckout,
},
{
ViewName: "branches",
Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)},
Key: opts.GetKey(opts.Config.Branches.CreatePullRequest),
Handler: self.handleCreatePullRequestPress,
Description: self.c.Tr.LcCreatePullRequest,
},
{
ViewName: "branches",
Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)},
Key: opts.GetKey(opts.Config.Branches.ViewPullRequestOptions),
Handler: self.checkSelected(self.handleCreatePullRequestMenu),
Description: self.c.Tr.LcCreatePullRequestOptions,
OpensMenu: true,
},
{
ViewName: "branches",
Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)},
Key: opts.GetKey(opts.Config.Branches.CopyPullRequestURL),
Handler: self.handleCopyPullRequestURLPress,
Description: self.c.Tr.LcCopyPullRequestURL,
},
{
ViewName: "branches",
Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)},
Key: opts.GetKey(opts.Config.Branches.CheckoutBranchByName),
Handler: self.handleCheckoutByName,
Description: self.c.Tr.LcCheckoutByName,
},
{
ViewName: "branches",
Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)},
Key: opts.GetKey(opts.Config.Branches.ForceCheckoutBranch),
Handler: self.handleForceCheckout,
Description: self.c.Tr.LcForceCheckout,
},
{
ViewName: "branches",
Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)},
Key: opts.GetKey(opts.Config.Universal.New),
Handler: self.checkSelected(self.handleNewBranchOffBranch),
Description: self.c.Tr.LcNewBranch,
},
{
ViewName: "branches",
Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)},
Key: opts.GetKey(opts.Config.Universal.Remove),
Handler: self.checkSelectedAndReal(self.handleDeleteBranch),
Description: self.c.Tr.LcDeleteBranch,
},
{
ViewName: "branches",
Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)},
Key: opts.GetKey(opts.Config.Branches.RebaseBranch),
Handler: opts.Guards.OutsideFilterMode(self.handleRebaseOntoLocalBranch),
Description: self.c.Tr.LcRebaseBranch,
},
{
ViewName: "branches",
Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)},
Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch),
Handler: opts.Guards.OutsideFilterMode(self.handleMerge),
Description: self.c.Tr.LcMergeIntoCurrentBranch,
},
{
ViewName: "branches",
Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)},
Key: opts.GetKey(opts.Config.Branches.FastForward),
Handler: self.checkSelectedAndReal(self.handleFastForward),
Description: self.c.Tr.FastForward,
},
{
ViewName: "branches",
Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)},
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
Handler: self.checkSelected(self.handleCreateResetToBranchMenu),
Description: self.c.Tr.LcViewResetOptions,
OpensMenu: true,
},
{
ViewName: "branches",
Contexts: []string{string(context.LOCAL_BRANCHES_CONTEXT_KEY)},
Key: opts.GetKey(opts.Config.Branches.RenameBranch),
Handler: self.checkSelectedAndReal(self.handleRenameBranch),
Description: self.c.Tr.LcRenameBranch,
},
}
}
func (self *BranchesController) Context() types.Context {
return self.context()
}
func (self *BranchesController) context() *context.BranchesContext {
return self.contexts.Branches
}
func (self *BranchesController) handleBranchPress() error {
branch := self.context().GetSelected()
if branch == nil {
return nil
}
if branch == self.helpers.Refs.GetCheckedOutRef() {
return self.c.ErrorMsg(self.c.Tr.AlreadyCheckedOutBranch)
}
self.c.LogAction(self.c.Tr.Actions.CheckoutBranch)
return self.helpers.Refs.CheckoutRef(branch.Name, types.CheckoutRefOptions{})
}
func (self *BranchesController) handleCreatePullRequestPress() error {
branch := self.context().GetSelected()
return self.createPullRequest(branch.Name, "")
}
func (self *BranchesController) handleCreatePullRequestMenu(selectedBranch *models.Branch) error {
checkedOutBranch := self.helpers.Refs.GetCheckedOutRef()
return self.createPullRequestMenu(selectedBranch, checkedOutBranch)
}
func (self *BranchesController) handleCopyPullRequestURLPress() error {
branch := self.context().GetSelected()
branchExistsOnRemote := self.git.Remote.CheckRemoteBranchExists(branch.Name)
if !branchExistsOnRemote {
return self.c.Error(errors.New(self.c.Tr.NoBranchOnRemote))
}
url, err := self.helpers.Host.GetPullRequestURL(branch.Name, "")
if err != nil {
return self.c.Error(err)
}
self.c.LogAction(self.c.Tr.Actions.CopyPullRequestURL)
if err := self.os.CopyToClipboard(url); err != nil {
return self.c.Error(err)
}
self.c.Toast(self.c.Tr.PullRequestURLCopiedToClipboard)
return nil
}
func (self *BranchesController) handleForceCheckout() error {
branch := self.context().GetSelected()
message := self.c.Tr.SureForceCheckout
title := self.c.Tr.ForceCheckoutBranch
return self.c.Ask(types.AskOpts{
Title: title,
Prompt: message,
HandleConfirm: func() error {
self.c.LogAction(self.c.Tr.Actions.ForceCheckoutBranch)
if err := self.git.Branch.Checkout(branch.Name, git_commands.CheckoutOptions{Force: true}); err != nil {
_ = self.c.Error(err)
}
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
},
})
}
func (self *BranchesController) handleCheckoutByName() error {
return self.c.Prompt(types.PromptOpts{
Title: self.c.Tr.BranchName + ":",
FindSuggestionsFunc: self.helpers.Suggestions.GetRefsSuggestionsFunc(),
HandleConfirm: func(response string) error {
self.c.LogAction("Checkout branch")
return self.helpers.Refs.CheckoutRef(response, types.CheckoutRefOptions{
OnRefNotFound: func(ref string) error {
return self.c.Ask(types.AskOpts{
Title: self.c.Tr.BranchNotFoundTitle,
Prompt: fmt.Sprintf("%s %s%s", self.c.Tr.BranchNotFoundPrompt, ref, "?"),
HandleConfirm: func() error {
return self.createNewBranchWithName(ref)
},
})
},
})
}},
)
}
func (self *BranchesController) createNewBranchWithName(newBranchName string) error {
branch := self.context().GetSelected()
if branch == nil {
return nil
}
if err := self.git.Branch.New(newBranchName, branch.Name); err != nil {
return self.c.Error(err)
}
self.context().SetSelectedLineIdx(0)
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
}
func (self *BranchesController) handleDeleteBranch(branch *models.Branch) error {
return self.deleteBranch(branch, false)
}
func (self *BranchesController) deleteBranch(branch *models.Branch, force bool) error {
checkedOutBranch := self.helpers.Refs.GetCheckedOutRef()
if checkedOutBranch.Name == branch.Name {
return self.c.ErrorMsg(self.c.Tr.CantDeleteCheckOutBranch)
}
return self.deleteNamedBranch(branch, force)
}
func (self *BranchesController) deleteNamedBranch(selectedBranch *models.Branch, force bool) error {
title := self.c.Tr.DeleteBranch
var templateStr string
if force {
templateStr = self.c.Tr.ForceDeleteBranchMessage
} else {
templateStr = self.c.Tr.DeleteBranchMessage
}
message := utils.ResolvePlaceholderString(
templateStr,
map[string]string{
"selectedBranchName": selectedBranch.Name,
},
)
return self.c.Ask(types.AskOpts{
Title: title,
Prompt: message,
HandleConfirm: func() error {
self.c.LogAction(self.c.Tr.Actions.DeleteBranch)
if err := self.git.Branch.Delete(selectedBranch.Name, force); err != nil {
errMessage := err.Error()
if !force && strings.Contains(errMessage, "git branch -D ") {
return self.deleteNamedBranch(selectedBranch, true)
}
return self.c.ErrorMsg(errMessage)
}
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}})
},
})
}
func (self *BranchesController) handleMerge() error {
selectedBranchName := self.context().GetSelected().Name
return self.helpers.MergeAndRebase.MergeRefIntoCheckedOutBranch(selectedBranchName)
}
func (self *BranchesController) handleRebaseOntoLocalBranch() error {
selectedBranchName := self.context().GetSelected().Name
return self.helpers.MergeAndRebase.RebaseOntoRef(selectedBranchName)
}
func (self *BranchesController) handleFastForward(branch *models.Branch) error {
if !branch.IsTrackingRemote() {
return self.c.ErrorMsg(self.c.Tr.FwdNoUpstream)
}
if !branch.RemoteBranchStoredLocally() {
return self.c.ErrorMsg(self.c.Tr.FwdNoLocalUpstream)
}
if branch.HasCommitsToPush() {
return self.c.ErrorMsg(self.c.Tr.FwdCommitsToPush)
}
action := self.c.Tr.Actions.FastForwardBranch
message := utils.ResolvePlaceholderString(
self.c.Tr.Fetching,
map[string]string{
"from": fmt.Sprintf("%s/%s", branch.UpstreamRemote, branch.UpstreamBranch),
"to": branch.Name,
},
)
return self.c.WithLoaderPanel(message, func() error {
if branch == self.helpers.Refs.GetCheckedOutRef() {
self.c.LogAction(action)
err := self.git.Sync.Pull(
git_commands.PullOptions{
RemoteName: branch.UpstreamRemote,
BranchName: branch.Name,
FastForwardOnly: true,
},
)
if err != nil {
_ = self.c.Error(err)
}
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
} else {
self.c.LogAction(action)
err := self.git.Sync.FastForward(branch.Name, branch.UpstreamRemote, branch.UpstreamBranch)
if err != nil {
_ = self.c.Error(err)
}
_ = self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}})
}
return nil
})
}
func (self *BranchesController) handleCreateResetToBranchMenu(selectedBranch *models.Branch) error {
return self.helpers.Refs.CreateGitResetMenu(selectedBranch.Name)
}
func (self *BranchesController) handleRenameBranch(branch *models.Branch) error {
promptForNewName := func() error {
return self.c.Prompt(types.PromptOpts{
Title: self.c.Tr.NewBranchNamePrompt + " " + branch.Name + ":",
InitialContent: branch.Name,
HandleConfirm: func(newBranchName string) error {
self.c.LogAction(self.c.Tr.Actions.RenameBranch)
if err := self.git.Branch.Rename(branch.Name, newBranchName); err != nil {
return self.c.Error(err)
}
// need to find where the branch is now so that we can re-select it. That means we need to refetch the branches synchronously and then find our branch
_ = self.c.Refresh(types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{types.BRANCHES}})
// now that we've got our stuff again we need to find that branch and reselect it.
for i, newBranch := range self.model.Branches {
if newBranch.Name == newBranchName {
self.context().SetSelectedLineIdx(i)
if err := self.context().HandleRender(); err != nil {
return err
}
}
}
return nil
},
})
}
// I could do an explicit check here for whether the branch is tracking a remote branch
// but if we've selected it we'll already know that via Pullables and Pullables.
// Bit of a hack but I'm lazy.
if !branch.IsTrackingRemote() {
return promptForNewName()
}
return self.c.Ask(types.AskOpts{
Title: self.c.Tr.LcRenameBranch,
Prompt: self.c.Tr.RenameBranchWarning,
HandleConfirm: promptForNewName,
})
}
func (self *BranchesController) handleNewBranchOffBranch(selectedBranch *models.Branch) error {
return self.helpers.Refs.NewBranch(selectedBranch.RefName(), selectedBranch.RefName(), "")
}
func (self *BranchesController) createPullRequestMenu(selectedBranch *models.Branch, checkedOutBranch *models.Branch) error {
menuItems := make([]*types.MenuItem, 0, 4)
fromToDisplayStrings := func(from string, to string) []string {
return []string{fmt.Sprintf("%s → %s", from, to)}
}
menuItemsForBranch := func(branch *models.Branch) []*types.MenuItem {
return []*types.MenuItem{
{
DisplayStrings: fromToDisplayStrings(branch.Name, self.c.Tr.LcDefaultBranch),
OnPress: func() error {
return self.createPullRequest(branch.Name, "")
},
},
{
DisplayStrings: fromToDisplayStrings(branch.Name, self.c.Tr.LcSelectBranch),
OnPress: func() error {
return self.c.Prompt(types.PromptOpts{
Title: branch.Name + " →",
FindSuggestionsFunc: self.helpers.Suggestions.GetBranchNameSuggestionsFunc(),
HandleConfirm: func(targetBranchName string) error {
return self.createPullRequest(branch.Name, targetBranchName)
}},
)
},
},
}
}
if selectedBranch != checkedOutBranch {
menuItems = append(menuItems,
&types.MenuItem{
DisplayStrings: fromToDisplayStrings(checkedOutBranch.Name, selectedBranch.Name),
OnPress: func() error {
return self.createPullRequest(checkedOutBranch.Name, selectedBranch.Name)
},
},
)
menuItems = append(menuItems, menuItemsForBranch(checkedOutBranch)...)
}
menuItems = append(menuItems, menuItemsForBranch(selectedBranch)...)
return self.c.Menu(types.CreateMenuOptions{Title: fmt.Sprintf(self.c.Tr.CreatePullRequestOptions), Items: menuItems})
}
func (self *BranchesController) createPullRequest(from string, to string) error {
url, err := self.helpers.Host.GetPullRequestURL(from, to)
if err != nil {
return self.c.Error(err)
}
self.c.LogAction(self.c.Tr.Actions.OpenPullRequest)
if err := self.os.OpenLink(url); err != nil {
return self.c.Error(err)
}
return nil
}
func (self *BranchesController) checkSelected(callback func(*models.Branch) error) func() error {
return func() error {
selectedItem := self.context().GetSelected()
if selectedItem == nil {
return nil
}
return callback(selectedItem)
}
}
func (self *BranchesController) checkSelectedAndReal(callback func(*models.Branch) error) func() error {
return func() error {
selectedItem := self.context().GetSelected()
if selectedItem == nil || !selectedItem.IsRealBranch() {
return nil
}
return callback(selectedItem)
}
}

View File

@ -0,0 +1,39 @@
package controllers
import (
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
type controllerCommon struct {
c *types.HelperCommon
os *oscommands.OSCommand
git *commands.GitCommand
helpers *helpers.Helpers
model *types.Model
contexts *context.ContextTree
modes *types.Modes
}
func NewControllerCommon(
c *types.HelperCommon,
os *oscommands.OSCommand,
git *commands.GitCommand,
helpers *helpers.Helpers,
model *types.Model,
contexts *context.ContextTree,
modes *types.Modes,
) *controllerCommon {
return &controllerCommon{
c: c,
os: os,
git: git,
helpers: helpers,
model: model,
contexts: contexts,
modes: modes,
}
}

View File

@ -6,7 +6,7 @@ import (
"strings" "strings"
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"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/config" "github.com/jesseduffield/lazygit/pkg/config"
@ -17,73 +17,33 @@ import (
) )
type FilesController struct { type FilesController struct {
// I've said publicly that I'm against single-letter variable names but in this baseController
// case I would actually prefer a _zero_ letter variable name in the form of *controllerCommon
// struct embedding, but Go does not allow hiding public fields in an embedded struct
// to the client
c *types.ControllerCommon
context *context.WorkingTreeContext
model *types.Model
git *commands.GitCommand
os *oscommands.OSCommand
getSelectedFileNode func() *filetree.FileNode
contexts *context.ContextTree
enterSubmodule func(submodule *models.SubmoduleConfig) error enterSubmodule func(submodule *models.SubmoduleConfig) error
getSubmodules func() []*models.SubmoduleConfig
setCommitMessage func(message string) setCommitMessage func(message string)
getCheckedOutBranch func() *models.Branch
withGpgHandling func(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error withGpgHandling func(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error
getFailedCommitMessage func() string getFailedCommitMessage func() string
getSelectedPath func() string
switchToMergeFn func(path string) error switchToMergeFn func(path string) error
suggestionsHelper ISuggestionsHelper
refsHelper IRefsHelper
filesHelper IFilesHelper
workingTreeHelper IWorkingTreeHelper
} }
var _ types.IController = &FilesController{} var _ types.IController = &FilesController{}
func NewFilesController( func NewFilesController(
c *types.ControllerCommon, common *controllerCommon,
context *context.WorkingTreeContext,
model *types.Model,
git *commands.GitCommand,
os *oscommands.OSCommand,
getSelectedFileNode func() *filetree.FileNode,
allContexts *context.ContextTree,
enterSubmodule func(submodule *models.SubmoduleConfig) error, enterSubmodule func(submodule *models.SubmoduleConfig) error,
getSubmodules func() []*models.SubmoduleConfig,
setCommitMessage func(message string), setCommitMessage func(message string),
withGpgHandling func(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error, withGpgHandling func(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error,
getFailedCommitMessage func() string, getFailedCommitMessage func() string,
getSelectedPath func() string,
switchToMergeFn func(path string) error, switchToMergeFn func(path string) error,
suggestionsHelper ISuggestionsHelper,
refsHelper IRefsHelper,
filesHelper IFilesHelper,
workingTreeHelper IWorkingTreeHelper,
) *FilesController { ) *FilesController {
return &FilesController{ return &FilesController{
c: c, controllerCommon: common,
context: context,
model: model,
git: git,
os: os,
getSelectedFileNode: getSelectedFileNode,
contexts: allContexts,
enterSubmodule: enterSubmodule, enterSubmodule: enterSubmodule,
getSubmodules: getSubmodules,
setCommitMessage: setCommitMessage, setCommitMessage: setCommitMessage,
withGpgHandling: withGpgHandling, withGpgHandling: withGpgHandling,
getFailedCommitMessage: getFailedCommitMessage, getFailedCommitMessage: getFailedCommitMessage,
getSelectedPath: getSelectedPath,
switchToMergeFn: switchToMergeFn, switchToMergeFn: switchToMergeFn,
suggestionsHelper: suggestionsHelper,
refsHelper: refsHelper,
filesHelper: filesHelper,
workingTreeHelper: workingTreeHelper,
} }
} }
@ -96,7 +56,7 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
}, },
// { // {
// Key: gocui.MouseLeft, // Key: gocui.MouseLeft,
// Handler: func() error { return self.context.HandleClick(self.checkSelectedFileNode(self.press)) }, // Handler: func() error { return self.context().HandleClick(self.checkSelectedFileNode(self.press)) },
// }, // },
{ {
Key: opts.GetKey("<c-b>"), // TODO: softcode Key: opts.GetKey("<c-b>"), // TODO: softcode
@ -187,6 +147,11 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
Handler: self.OpenMergeTool, Handler: self.OpenMergeTool,
Description: self.c.Tr.LcOpenMergeTool, Description: self.c.Tr.LcOpenMergeTool,
}, },
{
Key: opts.GetKey(opts.Config.Files.Fetch),
Handler: self.fetch,
Description: self.c.Tr.LcFetch,
},
} }
} }
@ -249,12 +214,12 @@ func (self *FilesController) press(node *filetree.FileNode) error {
return err return err
} }
return self.context.HandleFocus() return self.context().HandleFocus()
} }
func (self *FilesController) checkSelectedFileNode(callback func(*filetree.FileNode) error) func() error { func (self *FilesController) checkSelectedFileNode(callback func(*filetree.FileNode) error) func() error {
return func() error { return func() error {
node := self.getSelectedFileNode() node := self.context().GetSelectedFileNode()
if node == nil { if node == nil {
return nil return nil
} }
@ -264,11 +229,15 @@ func (self *FilesController) checkSelectedFileNode(callback func(*filetree.FileN
} }
func (self *FilesController) Context() types.Context { func (self *FilesController) Context() types.Context {
return self.context return self.context()
}
func (self *FilesController) context() *context.WorkingTreeContext {
return self.contexts.Files
} }
func (self *FilesController) getSelectedFile() *models.File { func (self *FilesController) getSelectedFile() *models.File {
node := self.getSelectedFileNode() node := self.context().GetSelectedFileNode()
if node == nil { if node == nil {
return nil return nil
} }
@ -280,7 +249,7 @@ func (self *FilesController) enter() error {
} }
func (self *FilesController) EnterFile(opts types.OnFocusOpts) error { func (self *FilesController) EnterFile(opts types.OnFocusOpts) error {
node := self.getSelectedFileNode() node := self.context().GetSelectedFileNode()
if node == nil { if node == nil {
return nil return nil
} }
@ -291,7 +260,7 @@ func (self *FilesController) EnterFile(opts types.OnFocusOpts) error {
file := node.File file := node.File
submoduleConfigs := self.getSubmodules() submoduleConfigs := self.model.Submodules
if file.IsSubmodule(submoduleConfigs) { if file.IsSubmodule(submoduleConfigs) {
submoduleConfig := file.SubmoduleConfig(submoduleConfigs) submoduleConfig := file.SubmoduleConfig(submoduleConfigs)
return self.enterSubmodule(submoduleConfig) return self.enterSubmodule(submoduleConfig)
@ -410,7 +379,7 @@ func (self *FilesController) commitPrefixConfigForRepo() *config.CommitPrefixCon
} }
func (self *FilesController) prepareFilesForCommit() error { func (self *FilesController) prepareFilesForCommit() error {
noStagedFiles := !self.workingTreeHelper.AnyStagedFiles() noStagedFiles := !self.helpers.WorkingTree.AnyStagedFiles()
if noStagedFiles && self.c.UserConfig.Gui.SkipNoStagedFilesWarning { if noStagedFiles && self.c.UserConfig.Gui.SkipNoStagedFilesWarning {
self.c.LogAction(self.c.Tr.Actions.StageAllFiles) self.c.LogAction(self.c.Tr.Actions.StageAllFiles)
err := self.git.WorkingTree.StageAll() err := self.git.WorkingTree.StageAll()
@ -442,7 +411,7 @@ func (self *FilesController) HandleCommitPress() error {
return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle) return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle)
} }
if !self.workingTreeHelper.AnyStagedFiles() { if !self.helpers.WorkingTree.AnyStagedFiles() {
return self.promptToStageAllAndRetry(self.HandleCommitPress) return self.promptToStageAllAndRetry(self.HandleCommitPress)
} }
@ -458,7 +427,7 @@ func (self *FilesController) HandleCommitPress() error {
if err != nil { if err != nil {
return self.c.ErrorMsg(fmt.Sprintf("%s: %s", self.c.Tr.LcCommitPrefixPatternError, err.Error())) return self.c.ErrorMsg(fmt.Sprintf("%s: %s", self.c.Tr.LcCommitPrefixPatternError, err.Error()))
} }
prefix := rgx.ReplaceAllString(self.getCheckedOutBranch().Name, prefixReplace) prefix := rgx.ReplaceAllString(self.helpers.Refs.GetCheckedOutRef().Name, prefixReplace)
self.setCommitMessage(prefix) self.setCommitMessage(prefix)
} }
} }
@ -493,7 +462,7 @@ func (self *FilesController) handleAmendCommitPress() error {
return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle) return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle)
} }
if !self.workingTreeHelper.AnyStagedFiles() { if !self.helpers.WorkingTree.AnyStagedFiles() {
return self.promptToStageAllAndRetry(self.handleAmendCommitPress) return self.promptToStageAllAndRetry(self.handleAmendCommitPress)
} }
@ -519,7 +488,7 @@ func (self *FilesController) HandleCommitEditorPress() error {
return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle) return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle)
} }
if !self.workingTreeHelper.AnyStagedFiles() { if !self.helpers.WorkingTree.AnyStagedFiles() {
return self.promptToStageAllAndRetry(self.HandleCommitEditorPress) return self.promptToStageAllAndRetry(self.HandleCommitEditorPress)
} }
@ -556,8 +525,8 @@ func (self *FilesController) handleStatusFilterPressed() error {
} }
func (self *FilesController) setStatusFiltering(filter filetree.FileTreeDisplayFilter) error { func (self *FilesController) setStatusFiltering(filter filetree.FileTreeDisplayFilter) error {
self.context.FileTreeViewModel.SetFilter(filter) self.context().FileTreeViewModel.SetFilter(filter)
return self.c.PostRefreshUpdate(self.context) return self.c.PostRefreshUpdate(self.context())
} }
func (self *FilesController) edit(node *filetree.FileNode) error { func (self *FilesController) edit(node *filetree.FileNode) error {
@ -565,16 +534,16 @@ func (self *FilesController) edit(node *filetree.FileNode) error {
return self.c.ErrorMsg(self.c.Tr.ErrCannotEditDirectory) return self.c.ErrorMsg(self.c.Tr.ErrCannotEditDirectory)
} }
return self.filesHelper.EditFile(node.GetPath()) return self.helpers.Files.EditFile(node.GetPath())
} }
func (self *FilesController) Open() error { func (self *FilesController) Open() error {
node := self.getSelectedFileNode() node := self.context().GetSelectedFileNode()
if node == nil { if node == nil {
return nil return nil
} }
return self.filesHelper.OpenFile(node.GetPath()) return self.helpers.Files.OpenFile(node.GetPath())
} }
func (self *FilesController) switchToMerge() error { func (self *FilesController) switchToMerge() error {
@ -613,16 +582,16 @@ func (self *FilesController) stash() error {
} }
func (self *FilesController) createResetMenu() error { func (self *FilesController) createResetMenu() error {
return self.refsHelper.CreateGitResetMenu("@{upstream}") return self.helpers.Refs.CreateGitResetMenu("@{upstream}")
} }
func (self *FilesController) handleToggleDirCollapsed() error { func (self *FilesController) handleToggleDirCollapsed() error {
node := self.getSelectedFileNode() node := self.context().GetSelectedFileNode()
if node == nil { if node == nil {
return nil return nil
} }
self.context.FileTreeViewModel.ToggleCollapsed(node.GetPath()) self.context().FileTreeViewModel.ToggleCollapsed(node.GetPath())
if err := self.c.PostRefreshUpdate(self.contexts.Files); err != nil { if err := self.c.PostRefreshUpdate(self.contexts.Files); err != nil {
self.c.Log.Error(err) self.c.Log.Error(err)
@ -632,9 +601,9 @@ func (self *FilesController) handleToggleDirCollapsed() error {
} }
func (self *FilesController) toggleTreeView() error { func (self *FilesController) toggleTreeView() error {
self.context.FileTreeViewModel.ToggleShowTree() self.context().FileTreeViewModel.ToggleShowTree()
return self.c.PostRefreshUpdate(self.context) return self.c.PostRefreshUpdate(self.context())
} }
func (self *FilesController) OpenMergeTool() error { func (self *FilesController) OpenMergeTool() error {
@ -654,7 +623,7 @@ func (self *FilesController) ResetSubmodule(submodule *models.SubmoduleConfig) e
return self.c.WithWaitingStatus(self.c.Tr.LcResettingSubmoduleStatus, func() error { return self.c.WithWaitingStatus(self.c.Tr.LcResettingSubmoduleStatus, func() error {
self.c.LogAction(self.c.Tr.Actions.ResetSubmodule) self.c.LogAction(self.c.Tr.Actions.ResetSubmodule)
file := self.workingTreeHelper.FileForSubmodule(submodule) file := self.helpers.WorkingTree.FileForSubmodule(submodule)
if file != nil { if file != nil {
if err := self.git.WorkingTree.UnStageFile(file.Names(), file.Tracked); err != nil { if err := self.git.WorkingTree.UnStageFile(file.Names(), file.Tracked); err != nil {
return self.c.Error(err) return self.c.Error(err)
@ -673,7 +642,7 @@ func (self *FilesController) ResetSubmodule(submodule *models.SubmoduleConfig) e
} }
func (self *FilesController) handleStashSave(stashFunc func(message string) error) error { func (self *FilesController) handleStashSave(stashFunc func(message string) error) error {
if !self.workingTreeHelper.IsWorkingTreeDirty() { if !self.helpers.WorkingTree.IsWorkingTreeDirty() {
return self.c.ErrorMsg(self.c.Tr.NoTrackedStagedFilesStash) return self.c.ErrorMsg(self.c.Tr.NoTrackedStagedFilesStash)
} }
@ -697,3 +666,25 @@ func (self *FilesController) onClickSecondary(opts gocui.ViewMouseBindingOpts) e
clickedViewLineIdx := opts.Cy + opts.Oy clickedViewLineIdx := opts.Cy + opts.Oy
return self.EnterFile(types.OnFocusOpts{ClickedViewName: "secondary", ClickedViewLineIdx: clickedViewLineIdx}) return self.EnterFile(types.OnFocusOpts{ClickedViewName: "secondary", ClickedViewLineIdx: clickedViewLineIdx})
} }
func (self *FilesController) fetch() error {
return self.c.WithLoaderPanel(self.c.Tr.FetchWait, func() error {
if err := self.fetchAux(); err != nil {
_ = self.c.Error(err)
}
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
})
}
func (self *FilesController) fetchAux() (err error) {
self.c.LogAction("Fetch")
err = self.git.Sync.Fetch(git_commands.FetchOptions{})
if err != nil && strings.Contains(err.Error(), "exit status 128") {
_ = self.c.ErrorMsg(self.c.Tr.PassUnameWrong)
}
_ = self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.BRANCHES, types.COMMITS, types.REMOTES, types.TAGS}, Mode: types.ASYNC})
return err
}

View File

@ -39,7 +39,7 @@ func (self *FilesController) remove(node *filetree.FileNode) error {
} else { } else {
file := node.File file := node.File
submodules := self.getSubmodules() submodules := self.model.Submodules
if file.IsSubmodule(submodules) { if file.IsSubmodule(submodules) {
submodule := file.SubmoduleConfig(submodules) submodule := file.SubmoduleConfig(submodules)

View File

@ -1,26 +1,22 @@
package controllers package controllers
import ( import (
"github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
) )
type GlobalController struct { type GlobalController struct {
baseController baseController
*controllerCommon
c *types.ControllerCommon
os *oscommands.OSCommand
} }
func NewGlobalController( func NewGlobalController(
c *types.ControllerCommon, common *controllerCommon,
os *oscommands.OSCommand,
) *GlobalController { ) *GlobalController {
return &GlobalController{ return &GlobalController{
baseController: baseController{}, baseController: baseController{},
c: c, controllerCommon: common,
os: os,
} }
} }
@ -63,7 +59,7 @@ func (self *GlobalController) GetCustomCommandsHistorySuggestionsFunc() func(str
// reversing so that we display the latest command first // reversing so that we display the latest command first
history := utils.Reverse(self.c.GetAppState().CustomCommandsHistory) history := utils.Reverse(self.c.GetAppState().CustomCommandsHistory)
return FuzzySearchFunc(history) return helpers.FuzzySearchFunc(history)
} }
func (self *GlobalController) Context() types.Context { func (self *GlobalController) Context() types.Context {

View File

@ -1,4 +1,4 @@
package controllers package helpers
import ( import (
"github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands"
@ -6,12 +6,12 @@ import (
) )
type BisectHelper struct { type BisectHelper struct {
c *types.ControllerCommon c *types.HelperCommon
git *commands.GitCommand git *commands.GitCommand
} }
func NewBisectHelper( func NewBisectHelper(
c *types.ControllerCommon, c *types.HelperCommon,
git *commands.GitCommand, git *commands.GitCommand,
) *BisectHelper { ) *BisectHelper {
return &BisectHelper{ return &BisectHelper{

View File

@ -1,4 +1,4 @@
package controllers package helpers
import ( import (
"github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands"
@ -9,25 +9,25 @@ import (
) )
type CherryPickHelper struct { type CherryPickHelper struct {
c *types.ControllerCommon c *types.HelperCommon
git *commands.GitCommand git *commands.GitCommand
contexts *context.ContextTree contexts *context.ContextTree
getData func() *cherrypicking.CherryPicking getData func() *cherrypicking.CherryPicking
rebaseHelper *RebaseHelper rebaseHelper *MergeAndRebaseHelper
} }
// I'm using the analogy of copy+paste in the terminology here because it's intuitively what's going on, // I'm using the analogy of copy+paste in the terminology here because it's intuitively what's going on,
// even if in truth we're running git cherry-pick // even if in truth we're running git cherry-pick
func NewCherryPickHelper( func NewCherryPickHelper(
c *types.ControllerCommon, c *types.HelperCommon,
git *commands.GitCommand, git *commands.GitCommand,
contexts *context.ContextTree, contexts *context.ContextTree,
getData func() *cherrypicking.CherryPicking, getData func() *cherrypicking.CherryPicking,
rebaseHelper *RebaseHelper, rebaseHelper *MergeAndRebaseHelper,
) *CherryPickHelper { ) *CherryPickHelper {
return &CherryPickHelper{ return &CherryPickHelper{
c: c, c: c,

View File

@ -1,4 +1,4 @@
package controllers package helpers
import ( import (
"github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands"
@ -14,13 +14,13 @@ type IFilesHelper interface {
} }
type FilesHelper struct { type FilesHelper struct {
c *types.ControllerCommon c *types.HelperCommon
git *commands.GitCommand git *commands.GitCommand
os *oscommands.OSCommand os *oscommands.OSCommand
} }
func NewFilesHelper( func NewFilesHelper(
c *types.ControllerCommon, c *types.HelperCommon,
git *commands.GitCommand, git *commands.GitCommand,
os *oscommands.OSCommand, os *oscommands.OSCommand,
) *FilesHelper { ) *FilesHelper {

View File

@ -0,0 +1,13 @@
package helpers
type Helpers struct {
Refs *RefsHelper
Bisect *BisectHelper
Suggestions *SuggestionsHelper
Files *FilesHelper
WorkingTree *WorkingTreeHelper
Tags *TagsHelper
MergeAndRebase *MergeAndRebaseHelper
CherryPick *CherryPickHelper
Host *HostHelper
}

View File

@ -0,0 +1,46 @@
package helpers
import (
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/hosting_service"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
// this helper just wraps our hosting_service package
type IHostHelper interface {
GetPullRequestURL(from string, to string) (string, error)
GetCommitURL(commitSha string) (string, error)
}
type HostHelper struct {
c *types.HelperCommon
git *commands.GitCommand
}
func NewHostHelper(
c *types.HelperCommon,
git *commands.GitCommand,
) *HostHelper {
return &HostHelper{
c: c,
git: git,
}
}
func (self *HostHelper) GetPullRequestURL(from string, to string) (string, error) {
return self.getHostingServiceMgr().GetPullRequestURL(from, to)
}
func (self *HostHelper) GetCommitURL(commitSha string) (string, error) {
return self.getHostingServiceMgr().GetCommitURL(commitSha)
}
// getting this on every request rather than storing it in state in case our remoteURL changes
// from one invocation to the next. Note however that we're currently caching config
// results so we might want to invalidate the cache here if it becomes a problem.
func (self *HostHelper) getHostingServiceMgr() *hosting_service.HostingServiceMgr {
remoteUrl := self.git.Config.GetRemoteURL()
configServices := self.c.UserConfig.Services
return hosting_service.NewHostingServiceMgr(self.c.Log, self.c.Tr, remoteUrl, configServices)
}

View File

@ -1,33 +1,38 @@
package controllers package helpers
import ( import (
"fmt" "fmt"
"strings" "strings"
"github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/types/enums" "github.com/jesseduffield/lazygit/pkg/commands/types/enums"
"github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
) )
type RebaseHelper struct { type MergeAndRebaseHelper struct {
c *types.ControllerCommon c *types.HelperCommon
contexts *context.ContextTree contexts *context.ContextTree
git *commands.GitCommand git *commands.GitCommand
takeOverMergeConflictScrolling func() takeOverMergeConflictScrolling func()
refsHelper *RefsHelper
} }
func NewRebaseHelper( func NewMergeAndRebaseHelper(
c *types.ControllerCommon, c *types.HelperCommon,
contexts *context.ContextTree, contexts *context.ContextTree,
git *commands.GitCommand, git *commands.GitCommand,
takeOverMergeConflictScrolling func(), takeOverMergeConflictScrolling func(),
) *RebaseHelper { refsHelper *RefsHelper,
return &RebaseHelper{ ) *MergeAndRebaseHelper {
return &MergeAndRebaseHelper{
c: c, c: c,
contexts: contexts, contexts: contexts,
git: git, git: git,
takeOverMergeConflictScrolling: takeOverMergeConflictScrolling, takeOverMergeConflictScrolling: takeOverMergeConflictScrolling,
refsHelper: refsHelper,
} }
} }
@ -39,7 +44,7 @@ const (
REBASE_OPTION_SKIP string = "skip" REBASE_OPTION_SKIP string = "skip"
) )
func (self *RebaseHelper) CreateRebaseOptionsMenu() error { func (self *MergeAndRebaseHelper) CreateRebaseOptionsMenu() error {
options := []string{REBASE_OPTION_CONTINUE, REBASE_OPTION_ABORT} options := []string{REBASE_OPTION_CONTINUE, REBASE_OPTION_ABORT}
if self.git.Status.WorkingTreeState() == enums.REBASE_MODE_REBASING { if self.git.Status.WorkingTreeState() == enums.REBASE_MODE_REBASING {
@ -68,7 +73,7 @@ func (self *RebaseHelper) CreateRebaseOptionsMenu() error {
return self.c.Menu(types.CreateMenuOptions{Title: title, Items: menuItems}) return self.c.Menu(types.CreateMenuOptions{Title: title, Items: menuItems})
} }
func (self *RebaseHelper) genericMergeCommand(command string) error { func (self *MergeAndRebaseHelper) genericMergeCommand(command string) error {
status := self.git.Status.WorkingTreeState() status := self.git.Status.WorkingTreeState()
if status != enums.REBASE_MODE_MERGING && status != enums.REBASE_MODE_REBASING { if status != enums.REBASE_MODE_MERGING && status != enums.REBASE_MODE_REBASING {
@ -120,7 +125,7 @@ func isMergeConflictErr(errStr string) bool {
return false return false
} }
func (self *RebaseHelper) CheckMergeOrRebase(result error) error { func (self *MergeAndRebaseHelper) CheckMergeOrRebase(result error) error {
if err := self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}); err != nil { if err := self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}); err != nil {
return err return err
} }
@ -154,7 +159,7 @@ func (self *RebaseHelper) CheckMergeOrRebase(result error) error {
} }
} }
func (self *RebaseHelper) AbortMergeOrRebaseWithConfirm() error { func (self *MergeAndRebaseHelper) AbortMergeOrRebaseWithConfirm() error {
// prompt user to confirm that they want to abort, then do it // prompt user to confirm that they want to abort, then do it
mode := self.workingTreeStateNoun() mode := self.workingTreeStateNoun()
return self.c.Ask(types.AskOpts{ return self.c.Ask(types.AskOpts{
@ -166,7 +171,7 @@ func (self *RebaseHelper) AbortMergeOrRebaseWithConfirm() error {
}) })
} }
func (self *RebaseHelper) workingTreeStateNoun() string { func (self *MergeAndRebaseHelper) workingTreeStateNoun() string {
workingTreeState := self.git.Status.WorkingTreeState() workingTreeState := self.git.Status.WorkingTreeState()
switch workingTreeState { switch workingTreeState {
case enums.REBASE_MODE_NONE: case enums.REBASE_MODE_NONE:
@ -179,7 +184,7 @@ func (self *RebaseHelper) workingTreeStateNoun() string {
} }
// PromptToContinueRebase asks the user if they want to continue the rebase/merge that's in progress // PromptToContinueRebase asks the user if they want to continue the rebase/merge that's in progress
func (self *RebaseHelper) PromptToContinueRebase() error { func (self *MergeAndRebaseHelper) PromptToContinueRebase() error {
self.takeOverMergeConflictScrolling() self.takeOverMergeConflictScrolling()
return self.c.Ask(types.AskOpts{ return self.c.Ask(types.AskOpts{
@ -190,3 +195,54 @@ func (self *RebaseHelper) PromptToContinueRebase() error {
}, },
}) })
} }
func (self *MergeAndRebaseHelper) RebaseOntoRef(ref string) error {
checkedOutBranch := self.refsHelper.GetCheckedOutRef().Name
if ref == checkedOutBranch {
return self.c.ErrorMsg(self.c.Tr.CantRebaseOntoSelf)
}
prompt := utils.ResolvePlaceholderString(
self.c.Tr.ConfirmRebase,
map[string]string{
"checkedOutBranch": checkedOutBranch,
"selectedBranch": ref,
},
)
return self.c.Ask(types.AskOpts{
Title: self.c.Tr.RebasingTitle,
Prompt: prompt,
HandleConfirm: func() error {
self.c.LogAction(self.c.Tr.Actions.RebaseBranch)
err := self.git.Rebase.RebaseBranch(ref)
return self.CheckMergeOrRebase(err)
},
})
}
func (self *MergeAndRebaseHelper) MergeRefIntoCheckedOutBranch(refName string) error {
if self.git.Branch.IsHeadDetached() {
return self.c.ErrorMsg("Cannot merge branch in detached head state. You might have checked out a commit directly or a remote branch, in which case you should checkout the local branch you want to be on")
}
checkedOutBranchName := self.refsHelper.GetCheckedOutRef().Name
if checkedOutBranchName == refName {
return self.c.ErrorMsg(self.c.Tr.CantMergeBranchIntoItself)
}
prompt := utils.ResolvePlaceholderString(
self.c.Tr.ConfirmMerge,
map[string]string{
"checkedOutBranch": checkedOutBranchName,
"selectedBranch": refName,
},
)
return self.c.Ask(types.AskOpts{
Title: self.c.Tr.MergingTitle,
Prompt: prompt,
HandleConfirm: func() error {
self.c.LogAction(self.c.Tr.Actions.Merge)
err := self.git.Branch.Merge(refName, git_commands.MergeOpts{})
return self.CheckMergeOrRebase(err)
},
})
}

View File

@ -1,4 +1,4 @@
package controllers package helpers
import ( import (
"fmt" "fmt"
@ -6,6 +6,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
@ -14,26 +15,30 @@ import (
type IRefsHelper interface { type IRefsHelper interface {
CheckoutRef(ref string, options types.CheckoutRefOptions) error CheckoutRef(ref string, options types.CheckoutRefOptions) error
GetCheckedOutRef() *models.Branch
CreateGitResetMenu(ref string) error CreateGitResetMenu(ref string) error
ResetToRef(ref string, strength string, envVars []string) error ResetToRef(ref string, strength string, envVars []string) error
NewBranch(from string, fromDescription string, suggestedBranchname string) error NewBranch(from string, fromDescription string, suggestedBranchname string) error
} }
type RefsHelper struct { type RefsHelper struct {
c *types.ControllerCommon c *types.HelperCommon
git *commands.GitCommand git *commands.GitCommand
contexts *context.ContextTree contexts *context.ContextTree
model *types.Model
} }
func NewRefsHelper( func NewRefsHelper(
c *types.ControllerCommon, c *types.HelperCommon,
git *commands.GitCommand, git *commands.GitCommand,
contexts *context.ContextTree, contexts *context.ContextTree,
model *types.Model,
) *RefsHelper { ) *RefsHelper {
return &RefsHelper{ return &RefsHelper{
c: c, c: c,
git: git, git: git,
contexts: contexts, contexts: contexts,
model: model,
} }
} }
@ -99,6 +104,14 @@ func (self *RefsHelper) CheckoutRef(ref string, options types.CheckoutRefOptions
}) })
} }
func (self *RefsHelper) GetCheckedOutRef() *models.Branch {
if len(self.model.Branches) == 0 {
return nil
}
return self.model.Branches[0]
}
func (self *RefsHelper) ResetToRef(ref string, strength string, envVars []string) error { func (self *RefsHelper) ResetToRef(ref string, strength string, envVars []string) error {
if err := self.git.Commit.ResetToCommit(ref, strength, envVars); err != nil { if err := self.git.Commit.ResetToCommit(ref, strength, envVars); err != nil {
return self.c.Error(err) return self.c.Error(err)

View File

@ -1,4 +1,4 @@
package controllers package helpers
import ( import (
"fmt" "fmt"
@ -30,7 +30,7 @@ type ISuggestionsHelper interface {
} }
type SuggestionsHelper struct { type SuggestionsHelper struct {
c *types.ControllerCommon c *types.HelperCommon
model *types.Model model *types.Model
refreshSuggestionsFn func() refreshSuggestionsFn func()
@ -39,7 +39,7 @@ type SuggestionsHelper struct {
var _ ISuggestionsHelper = &SuggestionsHelper{} var _ ISuggestionsHelper = &SuggestionsHelper{}
func NewSuggestionsHelper( func NewSuggestionsHelper(
c *types.ControllerCommon, c *types.HelperCommon,
model *types.Model, model *types.Model,
refreshSuggestionsFn func(), refreshSuggestionsFn func(),
) *SuggestionsHelper { ) *SuggestionsHelper {

View File

@ -1,4 +1,4 @@
package controllers package helpers
import ( import (
"github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands"
@ -10,11 +10,11 @@ import (
// and the commits context. // and the commits context.
type TagsHelper struct { type TagsHelper struct {
c *types.ControllerCommon c *types.HelperCommon
git *commands.GitCommand git *commands.GitCommand
} }
func NewTagsHelper(c *types.ControllerCommon, git *commands.GitCommand) *TagsHelper { func NewTagsHelper(c *types.HelperCommon, git *commands.GitCommand) *TagsHelper {
return &TagsHelper{ return &TagsHelper{
c: c, c: c,
git: git, git: git,

View File

@ -1,4 +1,4 @@
package controllers package helpers
import ( import (
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"

View File

@ -6,10 +6,10 @@ import (
) )
type ListControllerFactory struct { type ListControllerFactory struct {
c *types.ControllerCommon c *types.HelperCommon
} }
func NewListControllerFactory(c *types.ControllerCommon) *ListControllerFactory { func NewListControllerFactory(c *types.HelperCommon) *ListControllerFactory {
return &ListControllerFactory{ return &ListControllerFactory{
c: c, c: c,
} }
@ -25,7 +25,7 @@ func (self *ListControllerFactory) Create(context types.IListContext) *ListContr
type ListController struct { type ListController struct {
baseController baseController
c *types.ControllerCommon c *types.HelperCommon
context types.IListContext context types.IListContext
} }

View File

@ -4,80 +4,37 @@ import (
"fmt" "fmt"
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/hosting_service"
"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/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
) )
type ( type (
CheckoutRefFn func(refName string, opts types.CheckoutRefOptions) error
CreateGitResetMenuFn func(refName string) error
SwitchToCommitFilesContextFn func(SwitchToCommitFilesContextOpts) error SwitchToCommitFilesContextFn func(SwitchToCommitFilesContextOpts) error
GetHostingServiceMgrFn func() *hosting_service.HostingServiceMgr
PullFilesFn func() error PullFilesFn func() error
CheckMergeOrRebase func(error) error
) )
type LocalCommitsController struct { type LocalCommitsController struct {
baseController baseController
c *types.ControllerCommon *controllerCommon
context *context.LocalCommitsContext
os *oscommands.OSCommand
git *commands.GitCommand
tagsHelper *TagsHelper
refsHelper IRefsHelper
cherryPickHelper *CherryPickHelper
rebaseHelper *RebaseHelper
model *types.Model
CheckMergeOrRebase CheckMergeOrRebase
pullFiles PullFilesFn pullFiles PullFilesFn
getHostingServiceMgr GetHostingServiceMgrFn
switchToCommitFilesContext SwitchToCommitFilesContextFn switchToCommitFilesContext SwitchToCommitFilesContextFn
getShowWholeGitGraph func() bool
setShowWholeGitGraph func(bool)
} }
var _ types.IController = &LocalCommitsController{} var _ types.IController = &LocalCommitsController{}
func NewLocalCommitsController( func NewLocalCommitsController(
c *types.ControllerCommon, common *controllerCommon,
context *context.LocalCommitsContext,
os *oscommands.OSCommand,
git *commands.GitCommand,
tagsHelper *TagsHelper,
refsHelper IRefsHelper,
cherryPickHelper *CherryPickHelper,
rebaseHelper *RebaseHelper,
model *types.Model,
CheckMergeOrRebase CheckMergeOrRebase,
pullFiles PullFilesFn, pullFiles PullFilesFn,
getHostingServiceMgr GetHostingServiceMgrFn,
switchToCommitFilesContext SwitchToCommitFilesContextFn, switchToCommitFilesContext SwitchToCommitFilesContextFn,
getShowWholeGitGraph func() bool,
setShowWholeGitGraph func(bool),
) *LocalCommitsController { ) *LocalCommitsController {
return &LocalCommitsController{ return &LocalCommitsController{
baseController: baseController{}, baseController: baseController{},
c: c, controllerCommon: common,
context: context,
os: os,
git: git,
tagsHelper: tagsHelper,
refsHelper: refsHelper,
cherryPickHelper: cherryPickHelper,
rebaseHelper: rebaseHelper,
model: model,
CheckMergeOrRebase: CheckMergeOrRebase,
pullFiles: pullFiles, pullFiles: pullFiles,
getHostingServiceMgr: getHostingServiceMgr,
switchToCommitFilesContext: switchToCommitFilesContext, switchToCommitFilesContext: switchToCommitFilesContext,
getShowWholeGitGraph: getShowWholeGitGraph,
setShowWholeGitGraph: setShowWholeGitGraph,
} }
} }
@ -185,7 +142,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
}, },
// { // {
// Key: gocui.MouseLeft, // Key: gocui.MouseLeft,
// Handler: func() error { return self.context.HandleClick(self.checkSelected(self.enter)) }, // Handler: func() error { return self.context().HandleClick(self.checkSelected(self.enter)) },
// }, // },
} }
@ -305,7 +262,7 @@ func (self *LocalCommitsController) reword(commit *models.Commit) error {
InitialContent: message, InitialContent: message,
HandleConfirm: func(response string) error { HandleConfirm: func(response string) error {
self.c.LogAction(self.c.Tr.Actions.RewordCommit) self.c.LogAction(self.c.Tr.Actions.RewordCommit)
if err := self.git.Rebase.RewordCommit(self.model.Commits, self.context.GetSelectedLineIdx(), response); err != nil { if err := self.git.Rebase.RewordCommit(self.model.Commits, self.context().GetSelectedLineIdx(), response); err != nil {
return self.c.Error(err) return self.c.Error(err)
} }
@ -325,7 +282,7 @@ func (self *LocalCommitsController) rewordEditor() error {
self.c.LogAction(self.c.Tr.Actions.RewordCommit) self.c.LogAction(self.c.Tr.Actions.RewordCommit)
subProcess, err := self.git.Rebase.RewordCommitInEditor( subProcess, err := self.git.Rebase.RewordCommitInEditor(
self.model.Commits, self.context.GetSelectedLineIdx(), self.model.Commits, self.context().GetSelectedLineIdx(),
) )
if err != nil { if err != nil {
return self.c.Error(err) return self.c.Error(err)
@ -388,15 +345,15 @@ func (self *LocalCommitsController) pick() error {
} }
func (self *LocalCommitsController) interactiveRebase(action string) error { func (self *LocalCommitsController) interactiveRebase(action string) error {
err := self.git.Rebase.InteractiveRebase(self.model.Commits, self.context.GetSelectedLineIdx(), action) err := self.git.Rebase.InteractiveRebase(self.model.Commits, self.context().GetSelectedLineIdx(), action)
return self.CheckMergeOrRebase(err) return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
} }
// handleMidRebaseCommand sees if the selected commit is in fact a rebasing // handleMidRebaseCommand sees if the selected commit is in fact a rebasing
// commit meaning you are trying to edit the todo file rather than actually // commit meaning you are trying to edit the todo file rather than actually
// begin a rebase. It then updates the todo file with that action // begin a rebase. It then updates the todo file with that action
func (self *LocalCommitsController) handleMidRebaseCommand(action string) (bool, error) { func (self *LocalCommitsController) handleMidRebaseCommand(action string) (bool, error) {
selectedCommit := self.context.GetSelected() selectedCommit := self.context().GetSelected()
if selectedCommit.Status != "rebasing" { if selectedCommit.Status != "rebasing" {
return false, nil return false, nil
} }
@ -416,7 +373,7 @@ func (self *LocalCommitsController) handleMidRebaseCommand(action string) (bool,
) )
if err := self.git.Rebase.EditRebaseTodo( if err := self.git.Rebase.EditRebaseTodo(
self.context.GetSelectedLineIdx(), action, self.context().GetSelectedLineIdx(), action,
); err != nil { ); err != nil {
return false, self.c.Error(err) return false, self.c.Error(err)
} }
@ -427,7 +384,7 @@ func (self *LocalCommitsController) handleMidRebaseCommand(action string) (bool,
} }
func (self *LocalCommitsController) handleCommitMoveDown() error { func (self *LocalCommitsController) handleCommitMoveDown() error {
index := self.context.GetSelectedLineIdx() index := self.context().GetSelectedLineIdx()
commits := self.model.Commits commits := self.model.Commits
selectedCommit := self.model.Commits[index] selectedCommit := self.model.Commits[index]
if selectedCommit.Status == "rebasing" { if selectedCommit.Status == "rebasing" {
@ -443,7 +400,7 @@ func (self *LocalCommitsController) handleCommitMoveDown() error {
if err := self.git.Rebase.MoveTodoDown(index); err != nil { if err := self.git.Rebase.MoveTodoDown(index); err != nil {
return self.c.Error(err) return self.c.Error(err)
} }
self.context.MoveSelectedLine(1) self.context().MoveSelectedLine(1)
return self.c.Refresh(types.RefreshOptions{ return self.c.Refresh(types.RefreshOptions{
Mode: types.SYNC, Scope: []types.RefreshableView{types.REBASE_COMMITS}, Mode: types.SYNC, Scope: []types.RefreshableView{types.REBASE_COMMITS},
}) })
@ -453,14 +410,14 @@ func (self *LocalCommitsController) handleCommitMoveDown() error {
self.c.LogAction(self.c.Tr.Actions.MoveCommitDown) self.c.LogAction(self.c.Tr.Actions.MoveCommitDown)
err := self.git.Rebase.MoveCommitDown(self.model.Commits, index) err := self.git.Rebase.MoveCommitDown(self.model.Commits, index)
if err == nil { if err == nil {
self.context.MoveSelectedLine(1) self.context().MoveSelectedLine(1)
} }
return self.CheckMergeOrRebase(err) return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
}) })
} }
func (self *LocalCommitsController) handleCommitMoveUp() error { func (self *LocalCommitsController) handleCommitMoveUp() error {
index := self.context.GetSelectedLineIdx() index := self.context().GetSelectedLineIdx()
if index == 0 { if index == 0 {
return nil return nil
} }
@ -478,7 +435,7 @@ func (self *LocalCommitsController) handleCommitMoveUp() error {
if err := self.git.Rebase.MoveTodoDown(index - 1); err != nil { if err := self.git.Rebase.MoveTodoDown(index - 1); err != nil {
return self.c.Error(err) return self.c.Error(err)
} }
self.context.MoveSelectedLine(-1) self.context().MoveSelectedLine(-1)
return self.c.Refresh(types.RefreshOptions{ return self.c.Refresh(types.RefreshOptions{
Mode: types.SYNC, Scope: []types.RefreshableView{types.REBASE_COMMITS}, Mode: types.SYNC, Scope: []types.RefreshableView{types.REBASE_COMMITS},
}) })
@ -488,9 +445,9 @@ func (self *LocalCommitsController) handleCommitMoveUp() error {
self.c.LogAction(self.c.Tr.Actions.MoveCommitUp) self.c.LogAction(self.c.Tr.Actions.MoveCommitUp)
err := self.git.Rebase.MoveCommitDown(self.model.Commits, index-1) err := self.git.Rebase.MoveCommitDown(self.model.Commits, index-1)
if err == nil { if err == nil {
self.context.MoveSelectedLine(-1) self.context().MoveSelectedLine(-1)
} }
return self.CheckMergeOrRebase(err) return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
}) })
} }
@ -501,8 +458,8 @@ func (self *LocalCommitsController) handleCommitAmendTo() error {
HandleConfirm: func() error { HandleConfirm: func() error {
return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func() error { return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func() error {
self.c.LogAction(self.c.Tr.Actions.AmendCommit) self.c.LogAction(self.c.Tr.Actions.AmendCommit)
err := self.git.Rebase.AmendTo(self.context.GetSelected().Sha) err := self.git.Rebase.AmendTo(self.context().GetSelected().Sha)
return self.CheckMergeOrRebase(err) return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
}) })
}, },
}) })
@ -556,7 +513,7 @@ func (self *LocalCommitsController) createRevertMergeCommitMenu(commit *models.C
} }
func (self *LocalCommitsController) afterRevertCommit() error { func (self *LocalCommitsController) afterRevertCommit() error {
self.context.MoveSelectedLine(1) self.context().MoveSelectedLine(1)
return self.c.Refresh(types.RefreshOptions{ return self.c.Refresh(types.RefreshOptions{
Mode: types.BLOCK_UI, Scope: []types.RefreshableView{types.COMMITS, types.BRANCHES}, Mode: types.BLOCK_UI, Scope: []types.RefreshableView{types.COMMITS, types.BRANCHES},
}) })
@ -564,10 +521,9 @@ func (self *LocalCommitsController) afterRevertCommit() error {
func (self *LocalCommitsController) enter(commit *models.Commit) error { func (self *LocalCommitsController) enter(commit *models.Commit) error {
return self.switchToCommitFilesContext(SwitchToCommitFilesContextOpts{ return self.switchToCommitFilesContext(SwitchToCommitFilesContextOpts{
RefName: commit.Sha, RefName: commit.Sha,
CanRebase: true, CanRebase: true,
Context: self.context, Context: self.context(),
WindowName: "commits",
}) })
} }
@ -608,14 +564,14 @@ func (self *LocalCommitsController) handleSquashAllAboveFixupCommits(commit *mod
return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func() error { return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func() error {
self.c.LogAction(self.c.Tr.Actions.SquashAllAboveFixupCommits) self.c.LogAction(self.c.Tr.Actions.SquashAllAboveFixupCommits)
err := self.git.Rebase.SquashAllAboveFixupCommits(commit.Sha) err := self.git.Rebase.SquashAllAboveFixupCommits(commit.Sha)
return self.CheckMergeOrRebase(err) return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
}) })
}, },
}) })
} }
func (self *LocalCommitsController) handleTagCommit(commit *models.Commit) error { func (self *LocalCommitsController) handleTagCommit(commit *models.Commit) error {
return self.tagsHelper.CreateTagMenu(commit.Sha, func() {}) return self.helpers.Tags.CreateTagMenu(commit.Sha, func() {})
} }
func (self *LocalCommitsController) handleCheckoutCommit(commit *models.Commit) error { func (self *LocalCommitsController) handleCheckoutCommit(commit *models.Commit) error {
@ -624,19 +580,19 @@ func (self *LocalCommitsController) handleCheckoutCommit(commit *models.Commit)
Prompt: self.c.Tr.SureCheckoutThisCommit, Prompt: self.c.Tr.SureCheckoutThisCommit,
HandleConfirm: func() error { HandleConfirm: func() error {
self.c.LogAction(self.c.Tr.Actions.CheckoutCommit) self.c.LogAction(self.c.Tr.Actions.CheckoutCommit)
return self.refsHelper.CheckoutRef(commit.Sha, types.CheckoutRefOptions{}) return self.helpers.Refs.CheckoutRef(commit.Sha, types.CheckoutRefOptions{})
}, },
}) })
} }
func (self *LocalCommitsController) handleCreateCommitResetMenu(commit *models.Commit) error { func (self *LocalCommitsController) handleCreateCommitResetMenu(commit *models.Commit) error {
return self.refsHelper.CreateGitResetMenu(commit.Sha) return self.helpers.Refs.CreateGitResetMenu(commit.Sha)
} }
func (self *LocalCommitsController) openSearch() error { func (self *LocalCommitsController) openSearch() error {
// we usually lazyload these commits but now that we're searching we need to load them now // we usually lazyload these commits but now that we're searching we need to load them now
if self.context.GetLimitCommits() { if self.context().GetLimitCommits() {
self.context.SetLimitCommits(false) self.context().SetLimitCommits(false)
if err := self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.COMMITS}}); err != nil { if err := self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.COMMITS}}); err != nil {
return err return err
} }
@ -649,14 +605,14 @@ func (self *LocalCommitsController) openSearch() error {
func (self *LocalCommitsController) gotoBottom() error { func (self *LocalCommitsController) gotoBottom() error {
// we usually lazyload these commits but now that we're jumping to the bottom we need to load them now // we usually lazyload these commits but now that we're jumping to the bottom we need to load them now
if self.context.GetLimitCommits() { if self.context().GetLimitCommits() {
self.context.SetLimitCommits(false) self.context().SetLimitCommits(false)
if err := self.c.Refresh(types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{types.COMMITS}}); err != nil { if err := self.c.Refresh(types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{types.COMMITS}}); err != nil {
return err return err
} }
} }
self.context.SetSelectedLineIdx(self.context.GetItemsLength() - 1) self.context().SetSelectedLineIdx(self.context().GetItemsLength() - 1)
return nil return nil
} }
@ -684,10 +640,10 @@ func (self *LocalCommitsController) handleOpenLogMenu() error {
{ {
DisplayString: self.c.Tr.ToggleShowGitGraphAll, DisplayString: self.c.Tr.ToggleShowGitGraphAll,
OnPress: func() error { OnPress: func() error {
self.setShowWholeGitGraph(!self.getShowWholeGitGraph()) self.context().SetShowWholeGitGraph(!self.context().GetShowWholeGitGraph())
if self.getShowWholeGitGraph() { if self.context().GetShowWholeGitGraph() {
self.context.SetLimitCommits(false) self.context().SetLimitCommits(false)
} }
return self.c.WithWaitingStatus(self.c.Tr.LcLoadingCommits, func() error { return self.c.WithWaitingStatus(self.c.Tr.LcLoadingCommits, func() error {
@ -761,9 +717,7 @@ func (self *LocalCommitsController) handleOpenLogMenu() error {
} }
func (self *LocalCommitsController) handleOpenCommitInBrowser(commit *models.Commit) error { func (self *LocalCommitsController) handleOpenCommitInBrowser(commit *models.Commit) error {
hostingServiceMgr := self.getHostingServiceMgr() url, err := self.helpers.Host.GetCommitURL(commit.Sha)
url, err := hostingServiceMgr.GetCommitURL(commit.Sha)
if err != nil { if err != nil {
return self.c.Error(err) return self.c.Error(err)
} }
@ -778,7 +732,7 @@ func (self *LocalCommitsController) handleOpenCommitInBrowser(commit *models.Com
func (self *LocalCommitsController) checkSelected(callback func(*models.Commit) error) func() error { func (self *LocalCommitsController) checkSelected(callback func(*models.Commit) error) func() error {
return func() error { return func() error {
commit := self.context.GetSelected() commit := self.context().GetSelected()
if commit == nil { if commit == nil {
return nil return nil
} }
@ -788,21 +742,25 @@ func (self *LocalCommitsController) checkSelected(callback func(*models.Commit)
} }
func (self *LocalCommitsController) Context() types.Context { func (self *LocalCommitsController) Context() types.Context {
return self.context return self.context()
}
func (self *LocalCommitsController) context() *context.LocalCommitsContext {
return self.contexts.BranchCommits
} }
func (self *LocalCommitsController) newBranch(commit *models.Commit) error { func (self *LocalCommitsController) newBranch(commit *models.Commit) error {
return self.refsHelper.NewBranch(commit.RefName(), commit.Description(), "") return self.helpers.Refs.NewBranch(commit.RefName(), commit.Description(), "")
} }
func (self *LocalCommitsController) copy(commit *models.Commit) error { func (self *LocalCommitsController) copy(commit *models.Commit) error {
return self.cherryPickHelper.Copy(commit, self.model.Commits, self.context) return self.helpers.CherryPick.Copy(commit, self.model.Commits, self.context())
} }
func (self *LocalCommitsController) copyRange(*models.Commit) error { func (self *LocalCommitsController) copyRange(*models.Commit) error {
return self.cherryPickHelper.CopyRange(self.context.GetSelectedLineIdx(), self.model.Commits, self.context) return self.helpers.CherryPick.CopyRange(self.context().GetSelectedLineIdx(), self.model.Commits, self.context())
} }
func (self *LocalCommitsController) paste() error { func (self *LocalCommitsController) paste() error {
return self.cherryPickHelper.Paste() return self.helpers.CherryPick.Paste()
} }

View File

@ -7,22 +7,17 @@ import (
type MenuController struct { type MenuController struct {
baseController baseController
*controllerCommon
c *types.ControllerCommon
context *context.MenuContext
} }
var _ types.IController = &MenuController{} var _ types.IController = &MenuController{}
func NewMenuController( func NewMenuController(
c *types.ControllerCommon, common *controllerCommon,
context *context.MenuContext,
) *MenuController { ) *MenuController {
return &MenuController{ return &MenuController{
baseController: baseController{}, baseController: baseController{},
controllerCommon: common,
c: c,
context: context,
} }
} }
@ -50,7 +45,7 @@ func (self *MenuController) GetKeybindings(opts types.KeybindingsOpts) []*types.
} }
func (self *MenuController) press() error { func (self *MenuController) press() error {
selectedItem := self.context.GetSelected() selectedItem := self.context().GetSelected()
if err := self.c.PopContext(); err != nil { if err := self.c.PopContext(); err != nil {
return err return err
@ -64,5 +59,9 @@ func (self *MenuController) press() error {
} }
func (self *MenuController) Context() types.Context { func (self *MenuController) Context() types.Context {
return self.context return self.context()
}
func (self *MenuController) context() *context.MenuContext {
return self.contexts.Menu
} }

View File

@ -1,7 +1,6 @@
package controllers package controllers
import ( import (
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
@ -10,30 +9,22 @@ import (
type RemotesController struct { type RemotesController struct {
baseController baseController
*controllerCommon
c *types.ControllerCommon
context *context.RemotesContext context *context.RemotesContext
git *commands.GitCommand
setRemoteBranches func([]*models.RemoteBranch) setRemoteBranches func([]*models.RemoteBranch)
contexts *context.ContextTree
} }
var _ types.IController = &RemotesController{} var _ types.IController = &RemotesController{}
func NewRemotesController( func NewRemotesController(
c *types.ControllerCommon, common *controllerCommon,
context *context.RemotesContext,
git *commands.GitCommand,
contexts *context.ContextTree,
setRemoteBranches func([]*models.RemoteBranch), setRemoteBranches func([]*models.RemoteBranch),
) *RemotesController { ) *RemotesController {
return &RemotesController{ return &RemotesController{
baseController: baseController{}, baseController: baseController{},
c: c, controllerCommon: common,
git: git, context: common.contexts.Remotes,
contexts: contexts,
context: context,
setRemoteBranches: setRemoteBranches, setRemoteBranches: setRemoteBranches,
} }
} }

View File

@ -1,19 +1,14 @@
package controllers package controllers
import ( import (
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/loaders" "github.com/jesseduffield/lazygit/pkg/commands/loaders"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
) )
type SubCommitsSwitchControllerFactory struct { type SubCommitsSwitchControllerFactory struct {
c *types.ControllerCommon controllerCommon *controllerCommon
subCommitsContext *context.SubCommitsContext setSubCommits func([]*models.Commit)
git *commands.GitCommand
modes *types.Modes
setSubCommits func([]*models.Commit)
} }
var _ types.IController = &SubCommitsSwitchController{} var _ types.IController = &SubCommitsSwitchController{}
@ -25,40 +20,28 @@ type ContextWithRefName interface {
type SubCommitsSwitchController struct { type SubCommitsSwitchController struct {
baseController baseController
*controllerCommon
context ContextWithRefName
c *types.ControllerCommon setSubCommits func([]*models.Commit)
context ContextWithRefName
subCommitsContext *context.SubCommitsContext
git *commands.GitCommand
modes *types.Modes
setSubCommits func([]*models.Commit)
} }
func NewSubCommitsSwitchControllerFactory( func NewSubCommitsSwitchControllerFactory(
c *types.ControllerCommon, common *controllerCommon,
subCommitsContext *context.SubCommitsContext,
git *commands.GitCommand,
modes *types.Modes,
setSubCommits func([]*models.Commit), setSubCommits func([]*models.Commit),
) *SubCommitsSwitchControllerFactory { ) *SubCommitsSwitchControllerFactory {
return &SubCommitsSwitchControllerFactory{ return &SubCommitsSwitchControllerFactory{
c: c, controllerCommon: common,
subCommitsContext: subCommitsContext, setSubCommits: setSubCommits,
git: git,
modes: modes,
setSubCommits: setSubCommits,
} }
} }
func (self *SubCommitsSwitchControllerFactory) Create(context ContextWithRefName) *SubCommitsSwitchController { func (self *SubCommitsSwitchControllerFactory) Create(context ContextWithRefName) *SubCommitsSwitchController {
return &SubCommitsSwitchController{ return &SubCommitsSwitchController{
baseController: baseController{}, baseController: baseController{},
c: self.c, controllerCommon: self.controllerCommon,
context: context, context: context,
subCommitsContext: self.subCommitsContext, setSubCommits: self.setSubCommits,
git: self.git,
modes: self.modes,
setSubCommits: self.setSubCommits,
} }
} }
@ -94,10 +77,10 @@ func (self *SubCommitsSwitchController) viewCommits() error {
} }
self.setSubCommits(commits) self.setSubCommits(commits)
self.subCommitsContext.SetSelectedLineIdx(0) self.contexts.SubCommits.SetSelectedLineIdx(0)
self.subCommitsContext.SetParentContext(self.context) self.contexts.SubCommits.SetParentContext(self.context)
return self.c.PushContext(self.subCommitsContext) return self.c.PushContext(self.contexts.SubCommits)
} }
func (self *SubCommitsSwitchController) Context() types.Context { func (self *SubCommitsSwitchController) Context() types.Context {

View File

@ -5,7 +5,6 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/gui/style"
@ -14,10 +13,7 @@ import (
type SubmodulesController struct { type SubmodulesController struct {
baseController baseController
*controllerCommon
c *types.ControllerCommon
context *context.SubmodulesContext
git *commands.GitCommand
enterSubmodule func(submodule *models.SubmoduleConfig) error enterSubmodule func(submodule *models.SubmoduleConfig) error
} }
@ -25,17 +21,13 @@ type SubmodulesController struct {
var _ types.IController = &SubmodulesController{} var _ types.IController = &SubmodulesController{}
func NewSubmodulesController( func NewSubmodulesController(
c *types.ControllerCommon, controllerCommon *controllerCommon,
context *context.SubmodulesContext,
git *commands.GitCommand,
enterSubmodule func(submodule *models.SubmoduleConfig) error, enterSubmodule func(submodule *models.SubmoduleConfig) error,
) *SubmodulesController { ) *SubmodulesController {
return &SubmodulesController{ return &SubmodulesController{
baseController: baseController{}, baseController: baseController{},
c: c, controllerCommon: controllerCommon,
context: context, enterSubmodule: enterSubmodule,
git: git,
enterSubmodule: enterSubmodule,
} }
} }
@ -79,7 +71,7 @@ func (self *SubmodulesController) GetKeybindings(opts types.KeybindingsOpts) []*
}, },
// { // {
// Key: gocui.MouseLeft, // Key: gocui.MouseLeft,
// Handler: func() error { return self.context.HandleClick(self.checkSelected(self.enter)) }, // Handler: func() error { return self.context().HandleClick(self.checkSelected(self.enter)) },
// }, // },
} }
} }
@ -227,7 +219,7 @@ func (self *SubmodulesController) remove(submodule *models.SubmoduleConfig) erro
func (self *SubmodulesController) checkSelected(callback func(*models.SubmoduleConfig) error) func() error { func (self *SubmodulesController) checkSelected(callback func(*models.SubmoduleConfig) error) func() error {
return func() error { return func() error {
submodule := self.context.GetSelected() submodule := self.context().GetSelected()
if submodule == nil { if submodule == nil {
return nil return nil
} }
@ -237,5 +229,9 @@ func (self *SubmodulesController) checkSelected(callback func(*models.SubmoduleC
} }
func (self *SubmodulesController) Context() types.Context { func (self *SubmodulesController) Context() types.Context {
return self.context return self.context()
}
func (self *SubmodulesController) context() *context.SubmodulesContext {
return self.contexts.Submodules
} }

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
@ -12,35 +11,22 @@ import (
type SyncController struct { type SyncController struct {
baseController baseController
*controllerCommon
c *types.ControllerCommon getSuggestedRemote func() string
git *commands.GitCommand
getCheckedOutBranch func() *models.Branch
suggestionsHelper ISuggestionsHelper
getSuggestedRemote func() string
CheckMergeOrRebase func(error) error
} }
var _ types.IController = &SyncController{} var _ types.IController = &SyncController{}
func NewSyncController( func NewSyncController(
c *types.ControllerCommon, common *controllerCommon,
git *commands.GitCommand,
getCheckedOutBranch func() *models.Branch,
suggestionsHelper ISuggestionsHelper,
getSuggestedRemote func() string, getSuggestedRemote func() string,
CheckMergeOrRebase func(error) error,
) *SyncController { ) *SyncController {
return &SyncController{ return &SyncController{
baseController: baseController{}, baseController: baseController{},
c: c, controllerCommon: common,
git: git,
getCheckedOutBranch: getCheckedOutBranch, getSuggestedRemote: getSuggestedRemote,
suggestionsHelper: suggestionsHelper,
getSuggestedRemote: getSuggestedRemote,
CheckMergeOrRebase: CheckMergeOrRebase,
} }
} }
@ -75,7 +61,7 @@ func (self *SyncController) HandlePull() error {
func (self *SyncController) branchCheckedOut(f func(*models.Branch) error) func() error { func (self *SyncController) branchCheckedOut(f func(*models.Branch) error) func() error {
return func() error { return func() error {
currentBranch := self.getCheckedOutBranch() currentBranch := self.helpers.Refs.GetCheckedOutRef()
if currentBranch == nil { if currentBranch == nil {
// need to wait for branches to refresh // need to wait for branches to refresh
return nil return nil
@ -160,7 +146,7 @@ func (self *SyncController) promptForUpstream(currentBranch *models.Branch, onCo
return self.c.Prompt(types.PromptOpts{ return self.c.Prompt(types.PromptOpts{
Title: self.c.Tr.EnterUpstream, Title: self.c.Tr.EnterUpstream,
InitialContent: suggestedRemote + " " + currentBranch.Name, InitialContent: suggestedRemote + " " + currentBranch.Name,
FindSuggestionsFunc: self.suggestionsHelper.GetRemoteBranchesSuggestionsFunc(" "), FindSuggestionsFunc: self.helpers.Suggestions.GetRemoteBranchesSuggestionsFunc(" "),
HandleConfirm: onConfirm, HandleConfirm: onConfirm,
}) })
} }
@ -189,7 +175,7 @@ func (self *SyncController) pullWithLock(opts PullFilesOptions) error {
}, },
) )
return self.CheckMergeOrRebase(err) return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
} }
type pushOpts struct { type pushOpts struct {

View File

@ -1,7 +1,6 @@
package controllers package controllers
import ( import (
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
@ -10,43 +9,17 @@ import (
type TagsController struct { type TagsController struct {
baseController baseController
*controllerCommon
c *types.ControllerCommon
context *context.TagsContext
git *commands.GitCommand
contexts *context.ContextTree
tagsHelper *TagsHelper
refsHelper IRefsHelper
suggestionsHelper ISuggestionsHelper
switchToSubCommitsContext func(string) error
} }
var _ types.IController = &TagsController{} var _ types.IController = &TagsController{}
func NewTagsController( func NewTagsController(
c *types.ControllerCommon, common *controllerCommon,
context *context.TagsContext,
git *commands.GitCommand,
contexts *context.ContextTree,
tagsHelper *TagsHelper,
refsHelper IRefsHelper,
suggestionsHelper ISuggestionsHelper,
switchToSubCommitsContext func(string) error,
) *TagsController { ) *TagsController {
return &TagsController{ return &TagsController{
baseController: baseController{}, baseController: baseController{},
c: c, controllerCommon: common,
context: context,
git: git,
contexts: contexts,
tagsHelper: tagsHelper,
refsHelper: refsHelper,
suggestionsHelper: suggestionsHelper,
switchToSubCommitsContext: switchToSubCommitsContext,
} }
} }
@ -85,7 +58,7 @@ func (self *TagsController) GetKeybindings(opts types.KeybindingsOpts) []*types.
func (self *TagsController) checkout(tag *models.Tag) error { func (self *TagsController) checkout(tag *models.Tag) error {
self.c.LogAction(self.c.Tr.Actions.CheckoutTag) self.c.LogAction(self.c.Tr.Actions.CheckoutTag)
if err := self.refsHelper.CheckoutRef(tag.Name, types.CheckoutRefOptions{}); err != nil { if err := self.helpers.Refs.CheckoutRef(tag.Name, types.CheckoutRefOptions{}); err != nil {
return err return err
} }
return self.c.PushContext(self.contexts.Branches) return self.c.PushContext(self.contexts.Branches)
@ -123,7 +96,7 @@ func (self *TagsController) push(tag *models.Tag) error {
return self.c.Prompt(types.PromptOpts{ return self.c.Prompt(types.PromptOpts{
Title: title, Title: title,
InitialContent: "origin", InitialContent: "origin",
FindSuggestionsFunc: self.suggestionsHelper.GetRemoteSuggestionsFunc(), FindSuggestionsFunc: self.helpers.Suggestions.GetRemoteSuggestionsFunc(),
HandleConfirm: func(response string) error { HandleConfirm: func(response string) error {
return self.c.WithWaitingStatus(self.c.Tr.PushingTagStatus, func() error { return self.c.WithWaitingStatus(self.c.Tr.PushingTagStatus, func() error {
self.c.LogAction(self.c.Tr.Actions.PushTag) self.c.LogAction(self.c.Tr.Actions.PushTag)
@ -139,17 +112,17 @@ func (self *TagsController) push(tag *models.Tag) error {
} }
func (self *TagsController) createResetMenu(tag *models.Tag) error { func (self *TagsController) createResetMenu(tag *models.Tag) error {
return self.refsHelper.CreateGitResetMenu(tag.Name) return self.helpers.Refs.CreateGitResetMenu(tag.Name)
} }
func (self *TagsController) create() error { func (self *TagsController) create() error {
// leaving commit SHA blank so that we're just creating the tag for the current commit // leaving commit SHA blank so that we're just creating the tag for the current commit
return self.tagsHelper.CreateTagMenu("", func() { self.context.SetSelectedLineIdx(0) }) return self.helpers.Tags.CreateTagMenu("", func() { self.context().SetSelectedLineIdx(0) })
} }
func (self *TagsController) withSelectedTag(f func(tag *models.Tag) error) func() error { func (self *TagsController) withSelectedTag(f func(tag *models.Tag) error) func() error {
return func() error { return func() error {
tag := self.context.GetSelected() tag := self.context().GetSelected()
if tag == nil { if tag == nil {
return nil return nil
} }
@ -159,5 +132,9 @@ func (self *TagsController) withSelectedTag(f func(tag *models.Tag) error) func(
} }
func (self *TagsController) Context() types.Context { func (self *TagsController) Context() types.Context {
return self.context return self.context()
}
func (self *TagsController) context() *context.TagsContext {
return self.contexts.Tags
} }

View File

@ -6,8 +6,7 @@ import (
// all fields mandatory (except `CanRebase` because it's boolean) // all fields mandatory (except `CanRebase` because it's boolean)
type SwitchToCommitFilesContextOpts struct { type SwitchToCommitFilesContextOpts struct {
RefName string RefName string
CanRebase bool CanRebase bool
Context types.Context Context types.Context
WindowName string
} }

View File

@ -1,8 +1,6 @@
package controllers package controllers
import ( import (
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/types/enums" "github.com/jesseduffield/lazygit/pkg/commands/types/enums"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
@ -20,34 +18,17 @@ import (
type UndoController struct { type UndoController struct {
baseController baseController
*controllerCommon
c *types.ControllerCommon
git *commands.GitCommand
refsHelper IRefsHelper
workingTreeHelper IWorkingTreeHelper
getFilteredReflogCommits func() []*models.Commit
} }
var _ types.IController = &UndoController{} var _ types.IController = &UndoController{}
func NewUndoController( func NewUndoController(
c *types.ControllerCommon, common *controllerCommon,
git *commands.GitCommand,
refsHelper IRefsHelper,
workingTreeHelper IWorkingTreeHelper,
getFilteredReflogCommits func() []*models.Commit,
) *UndoController { ) *UndoController {
return &UndoController{ return &UndoController{
baseController: baseController{}, baseController: baseController{},
c: c, controllerCommon: common,
git: git,
refsHelper: refsHelper,
workingTreeHelper: workingTreeHelper,
getFilteredReflogCommits: getFilteredReflogCommits,
} }
} }
@ -109,7 +90,7 @@ func (self *UndoController) reflogUndo() error {
}) })
case CHECKOUT: case CHECKOUT:
self.c.LogAction(self.c.Tr.Actions.Undo) self.c.LogAction(self.c.Tr.Actions.Undo)
return true, self.refsHelper.CheckoutRef(action.from, types.CheckoutRefOptions{ return true, self.helpers.Refs.CheckoutRef(action.from, types.CheckoutRefOptions{
EnvVars: undoEnvVars, EnvVars: undoEnvVars,
WaitingStatus: undoingStatus, WaitingStatus: undoingStatus,
}) })
@ -147,7 +128,7 @@ func (self *UndoController) reflogRedo() error {
}) })
case CHECKOUT: case CHECKOUT:
self.c.LogAction(self.c.Tr.Actions.Redo) self.c.LogAction(self.c.Tr.Actions.Redo)
return true, self.refsHelper.CheckoutRef(action.to, types.CheckoutRefOptions{ return true, self.helpers.Refs.CheckoutRef(action.to, types.CheckoutRefOptions{
EnvVars: redoEnvVars, EnvVars: redoEnvVars,
WaitingStatus: redoingStatus, WaitingStatus: redoingStatus,
}) })
@ -168,7 +149,7 @@ func (self *UndoController) reflogRedo() error {
// Though we might support this later, hence the use of the CURRENT_REBASE action kind. // Though we might support this later, hence the use of the CURRENT_REBASE action kind.
func (self *UndoController) parseReflogForActions(onUserAction func(counter int, action reflogAction) (bool, error)) error { func (self *UndoController) parseReflogForActions(onUserAction func(counter int, action reflogAction) (bool, error)) error {
counter := 0 counter := 0
reflogCommits := self.getFilteredReflogCommits() reflogCommits := self.model.FilteredReflogCommits
rebaseFinishCommitSha := "" rebaseFinishCommitSha := ""
var action *reflogAction var action *reflogAction
for reflogCommitIdx, reflogCommit := range reflogCommits { for reflogCommitIdx, reflogCommit := range reflogCommits {
@ -222,14 +203,14 @@ type hardResetOptions struct {
// only to be used in the undo flow for now (does an autostash) // only to be used in the undo flow for now (does an autostash)
func (self *UndoController) hardResetWithAutoStash(commitSha string, options hardResetOptions) error { func (self *UndoController) hardResetWithAutoStash(commitSha string, options hardResetOptions) error {
reset := func() error { reset := func() error {
if err := self.refsHelper.ResetToRef(commitSha, "hard", options.EnvVars); err != nil { if err := self.helpers.Refs.ResetToRef(commitSha, "hard", options.EnvVars); err != nil {
return self.c.Error(err) return self.c.Error(err)
} }
return nil return nil
} }
// if we have any modified tracked files we need to ask the user if they want us to stash for them // if we have any modified tracked files we need to ask the user if they want us to stash for them
dirtyWorkingTree := self.workingTreeHelper.IsWorkingTreeDirty() dirtyWorkingTree := self.helpers.WorkingTree.IsWorkingTreeDirty()
if dirtyWorkingTree { if dirtyWorkingTree {
// offer to autostash changes // offer to autostash changes
return self.c.Ask(types.AskOpts{ return self.c.Ask(types.AskOpts{

View File

@ -54,7 +54,7 @@ func (gui *Gui) resolveTemplate(templateStr string, promptResponses []string) (s
SelectedCommitFile: gui.getSelectedCommitFile(), SelectedCommitFile: gui.getSelectedCommitFile(),
SelectedCommitFilePath: gui.getSelectedCommitFilePath(), SelectedCommitFilePath: gui.getSelectedCommitFilePath(),
SelectedSubCommit: gui.State.Contexts.SubCommits.GetSelected(), SelectedSubCommit: gui.State.Contexts.SubCommits.GetSelected(),
CheckedOutBranch: gui.getCheckedOutBranch(), CheckedOutBranch: gui.helpers.Refs.GetCheckedOutRef(),
PromptResponses: promptResponses, PromptResponses: promptResponses,
} }

View File

@ -189,19 +189,6 @@ func (gui *Gui) handleMouseDownMain() error {
return nil return nil
} }
func (gui *Gui) fetch() (err error) {
gui.c.LogAction("Fetch")
err = gui.git.Sync.Fetch(git_commands.FetchOptions{})
if err != nil && strings.Contains(err.Error(), "exit status 128") {
_ = gui.c.ErrorMsg(gui.c.Tr.PassUnameWrong)
}
_ = gui.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.BRANCHES, types.COMMITS, types.REMOTES, types.TAGS}, Mode: types.ASYNC})
return err
}
func (gui *Gui) backgroundFetch() (err error) { func (gui *Gui) backgroundFetch() (err error) {
err = gui.git.Sync.Fetch(git_commands.FetchOptions{Background: true}) err = gui.git.Sync.Fetch(git_commands.FetchOptions{Background: true})

View File

@ -20,6 +20,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/controllers" "github.com/jesseduffield/lazygit/pkg/gui/controllers"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/jesseduffield/lazygit/pkg/gui/lbl" "github.com/jesseduffield/lazygit/pkg/gui/lbl"
"github.com/jesseduffield/lazygit/pkg/gui/mergeconflicts" "github.com/jesseduffield/lazygit/pkg/gui/mergeconflicts"
"github.com/jesseduffield/lazygit/pkg/gui/modes/cherrypicking" "github.com/jesseduffield/lazygit/pkg/gui/modes/cherrypicking"
@ -67,17 +68,6 @@ func NewContextManager(initialContext types.Context) ContextManager {
} }
} }
type Helpers struct {
Refs *controllers.RefsHelper
Bisect *controllers.BisectHelper
Suggestions *controllers.SuggestionsHelper
Files *controllers.FilesHelper
WorkingTree *controllers.WorkingTreeHelper
Tags *controllers.TagsHelper
Rebase *controllers.RebaseHelper
CherryPick *controllers.CherryPickHelper
}
type Repo string type Repo string
// Gui wraps the gocui Gui object which handles rendering and events // Gui wraps the gocui Gui object which handles rendering and events
@ -144,9 +134,6 @@ type Gui struct {
// flag as to whether or not the diff view should ignore whitespace // flag as to whether or not the diff view should ignore whitespace
IgnoreWhitespaceInDiffView bool IgnoreWhitespaceInDiffView bool
// if this is true, we'll load our commits using `git log --all`
ShowWholeGitGraph bool
// we use this to decide whether we'll return to the original directory that // we use this to decide whether we'll return to the original directory that
// lazygit was opened in, or if we'll retain the one we're currently in. // lazygit was opened in, or if we'll retain the one we're currently in.
RetainOriginalDir bool RetainOriginalDir bool
@ -161,8 +148,8 @@ type Gui struct {
// process // process
InitialDir string InitialDir string
c *types.ControllerCommon c *types.HelperCommon
helpers *Helpers helpers *helpers.Helpers
} }
// we keep track of some stuff from one render to the next to see if certain // we keep track of some stuff from one render to the next to see if certain
@ -488,11 +475,11 @@ func NewGui(
) )
guiCommon := &guiCommon{gui: gui, IPopupHandler: gui.PopupHandler} guiCommon := &guiCommon{gui: gui, IPopupHandler: gui.PopupHandler}
controllerCommon := &types.ControllerCommon{IGuiCommon: guiCommon, Common: cmn} helperCommon := &types.HelperCommon{IGuiCommon: guiCommon, Common: cmn}
// storing this stuff on the gui for now to ease refactoring // storing this stuff on the gui for now to ease refactoring
// TODO: reset these controllers upon changing repos due to state changing // TODO: reset these controllers upon changing repos due to state changing
gui.c = controllerCommon gui.c = helperCommon
authors.SetCustomAuthors(gui.UserConfig.Gui.AuthorColors) authors.SetCustomAuthors(gui.UserConfig.Gui.AuthorColors)
presentation.SetCustomBranches(gui.UserConfig.Gui.BranchColors) presentation.SetCustomBranches(gui.UserConfig.Gui.BranchColors)
@ -503,21 +490,23 @@ func NewGui(
func (gui *Gui) resetControllers() { func (gui *Gui) resetControllers() {
controllerCommon := gui.c controllerCommon := gui.c
osCommand := gui.os osCommand := gui.os
rebaseHelper := controllers.NewRebaseHelper(controllerCommon, gui.State.Contexts, gui.git, gui.takeOverMergeConflictScrolling)
model := gui.State.Model model := gui.State.Model
gui.helpers = &Helpers{ refsHelper := helpers.NewRefsHelper(
Refs: controllers.NewRefsHelper( controllerCommon,
controllerCommon, gui.git,
gui.git, gui.State.Contexts,
gui.State.Contexts, model,
), )
Bisect: controllers.NewBisectHelper(controllerCommon, gui.git), rebaseHelper := helpers.NewMergeAndRebaseHelper(controllerCommon, gui.State.Contexts, gui.git, gui.takeOverMergeConflictScrolling, refsHelper)
Suggestions: controllers.NewSuggestionsHelper(controllerCommon, model, gui.refreshSuggestions), gui.helpers = &helpers.Helpers{
Files: controllers.NewFilesHelper(controllerCommon, gui.git, osCommand), Refs: refsHelper,
WorkingTree: controllers.NewWorkingTreeHelper(model), Bisect: helpers.NewBisectHelper(controllerCommon, gui.git),
Tags: controllers.NewTagsHelper(controllerCommon, gui.git), Suggestions: helpers.NewSuggestionsHelper(controllerCommon, model, gui.refreshSuggestions),
Rebase: rebaseHelper, Files: helpers.NewFilesHelper(controllerCommon, gui.git, osCommand),
CherryPick: controllers.NewCherryPickHelper( WorkingTree: helpers.NewWorkingTreeHelper(model),
Tags: helpers.NewTagsHelper(controllerCommon, gui.git),
MergeAndRebase: rebaseHelper,
CherryPick: helpers.NewCherryPickHelper(
controllerCommon, controllerCommon,
gui.git, gui.git,
gui.State.Contexts, gui.State.Contexts,
@ -526,109 +515,58 @@ func (gui *Gui) resetControllers() {
), ),
} }
syncController := controllers.NewSyncController( common := controllers.NewControllerCommon(
controllerCommon, controllerCommon,
osCommand,
gui.git, gui.git,
gui.getCheckedOutBranch, gui.helpers,
gui.helpers.Suggestions, model,
gui.State.Contexts,
gui.State.Modes,
)
syncController := controllers.NewSyncController(
common,
gui.getSuggestedRemote, gui.getSuggestedRemote,
gui.helpers.Rebase.CheckMergeOrRebase,
) )
submodulesController := controllers.NewSubmodulesController( submodulesController := controllers.NewSubmodulesController(
controllerCommon, common,
gui.State.Contexts.Submodules,
gui.git,
gui.enterSubmodule, gui.enterSubmodule,
) )
bisectController := controllers.NewBisectController( bisectController := controllers.NewBisectController(common)
controllerCommon,
gui.State.Contexts.BranchCommits,
gui.git,
gui.helpers.Bisect,
func() []*models.Commit { return gui.State.Model.Commits },
)
gui.Controllers = Controllers{ gui.Controllers = Controllers{
Submodules: submodulesController, Submodules: submodulesController,
Global: controllers.NewGlobalController( Global: controllers.NewGlobalController(common),
controllerCommon,
osCommand,
),
Files: controllers.NewFilesController( Files: controllers.NewFilesController(
controllerCommon, common,
gui.State.Contexts.Files,
model,
gui.git,
osCommand,
gui.getSelectedFileNode,
gui.State.Contexts,
gui.enterSubmodule, gui.enterSubmodule,
func() []*models.SubmoduleConfig { return gui.State.Model.Submodules },
gui.getSetTextareaTextFn(func() *gocui.View { return gui.Views.CommitMessage }), gui.getSetTextareaTextFn(func() *gocui.View { return gui.Views.CommitMessage }),
gui.withGpgHandling, gui.withGpgHandling,
func() string { return gui.State.failedCommitMessage }, func() string { return gui.State.failedCommitMessage },
gui.getSelectedPath,
gui.switchToMerge, gui.switchToMerge,
gui.helpers.Suggestions,
gui.helpers.Refs,
gui.helpers.Files,
gui.helpers.WorkingTree,
),
Tags: controllers.NewTagsController(
controllerCommon,
gui.State.Contexts.Tags,
gui.git,
gui.State.Contexts,
gui.helpers.Tags,
gui.helpers.Refs,
gui.helpers.Suggestions,
gui.switchToSubCommitsContext,
), ),
Tags: controllers.NewTagsController(common),
LocalCommits: controllers.NewLocalCommitsController( LocalCommits: controllers.NewLocalCommitsController(
controllerCommon, common,
gui.State.Contexts.BranchCommits,
osCommand,
gui.git,
gui.helpers.Tags,
gui.helpers.Refs,
gui.helpers.CherryPick,
gui.helpers.Rebase,
model,
gui.helpers.Rebase.CheckMergeOrRebase,
syncController.HandlePull, syncController.HandlePull,
gui.getHostingServiceMgr,
gui.SwitchToCommitFilesContext, gui.SwitchToCommitFilesContext,
func() bool { return gui.ShowWholeGitGraph },
func(value bool) { gui.ShowWholeGitGraph = value },
), ),
Remotes: controllers.NewRemotesController( Remotes: controllers.NewRemotesController(
controllerCommon, common,
gui.State.Contexts.Remotes,
gui.git,
gui.State.Contexts,
func(branches []*models.RemoteBranch) { gui.State.Model.RemoteBranches = branches }, func(branches []*models.RemoteBranch) { gui.State.Model.RemoteBranches = branches },
), ),
Menu: controllers.NewMenuController( Menu: controllers.NewMenuController(common),
controllerCommon, Undo: controllers.NewUndoController(common),
gui.State.Contexts.Menu,
),
Undo: controllers.NewUndoController(
controllerCommon,
gui.git,
gui.helpers.Refs,
gui.helpers.WorkingTree,
func() []*models.Commit { return gui.State.Model.FilteredReflogCommits },
),
Sync: syncController, Sync: syncController,
} }
branchesController := controllers.NewBranchesController(common)
switchToSubCommitsControllerFactory := controllers.NewSubCommitsSwitchControllerFactory( switchToSubCommitsControllerFactory := controllers.NewSubCommitsSwitchControllerFactory(
controllerCommon, common,
gui.State.Contexts.SubCommits,
gui.git,
gui.State.Modes,
func(commits []*models.Commit) { gui.State.Model.SubCommits = commits }, func(commits []*models.Commit) { gui.State.Model.SubCommits = commits },
) )
@ -640,6 +578,7 @@ func (gui *Gui) resetControllers() {
controllers.AttachControllers(context, switchToSubCommitsControllerFactory.Create(context)) controllers.AttachControllers(context, switchToSubCommitsControllerFactory.Create(context))
} }
controllers.AttachControllers(gui.State.Contexts.Branches, branchesController)
controllers.AttachControllers(gui.State.Contexts.Files, gui.Controllers.Files) controllers.AttachControllers(gui.State.Contexts.Files, gui.Controllers.Files)
controllers.AttachControllers(gui.State.Contexts.Tags, gui.Controllers.Tags) controllers.AttachControllers(gui.State.Contexts.Tags, gui.Controllers.Tags)
controllers.AttachControllers(gui.State.Contexts.Submodules, gui.Controllers.Submodules) controllers.AttachControllers(gui.State.Contexts.Submodules, gui.Controllers.Submodules)

File diff suppressed because it is too large Load Diff

View File

@ -73,7 +73,7 @@ func (gui *Gui) modeStatuses() []modeStatus {
formatWorkingTreeState(workingTreeState), style.FgYellow, formatWorkingTreeState(workingTreeState), style.FgYellow,
) )
}, },
reset: gui.helpers.Rebase.AbortMergeOrRebaseWithConfirm, reset: gui.helpers.MergeAndRebase.AbortMergeOrRebaseWithConfirm,
}, },
{ {
isActive: func() bool { isActive: func() bool {

View File

@ -102,7 +102,7 @@ func (gui *Gui) handleDeletePatchFromCommit() error {
commitIndex := gui.getPatchCommitIndex() commitIndex := gui.getPatchCommitIndex()
gui.c.LogAction(gui.c.Tr.Actions.RemovePatchFromCommit) gui.c.LogAction(gui.c.Tr.Actions.RemovePatchFromCommit)
err := gui.git.Patch.DeletePatchesFromCommit(gui.State.Model.Commits, commitIndex) err := gui.git.Patch.DeletePatchesFromCommit(gui.State.Model.Commits, commitIndex)
return gui.helpers.Rebase.CheckMergeOrRebase(err) return gui.helpers.MergeAndRebase.CheckMergeOrRebase(err)
}) })
} }
@ -119,7 +119,7 @@ func (gui *Gui) handleMovePatchToSelectedCommit() error {
commitIndex := gui.getPatchCommitIndex() commitIndex := gui.getPatchCommitIndex()
gui.c.LogAction(gui.c.Tr.Actions.MovePatchToSelectedCommit) gui.c.LogAction(gui.c.Tr.Actions.MovePatchToSelectedCommit)
err := gui.git.Patch.MovePatchToSelectedCommit(gui.State.Model.Commits, commitIndex, gui.State.Contexts.BranchCommits.GetSelectedLineIdx()) err := gui.git.Patch.MovePatchToSelectedCommit(gui.State.Model.Commits, commitIndex, gui.State.Contexts.BranchCommits.GetSelectedLineIdx())
return gui.helpers.Rebase.CheckMergeOrRebase(err) return gui.helpers.MergeAndRebase.CheckMergeOrRebase(err)
}) })
} }
@ -137,7 +137,7 @@ func (gui *Gui) handleMovePatchIntoWorkingTree() error {
commitIndex := gui.getPatchCommitIndex() commitIndex := gui.getPatchCommitIndex()
gui.c.LogAction(gui.c.Tr.Actions.MovePatchIntoIndex) gui.c.LogAction(gui.c.Tr.Actions.MovePatchIntoIndex)
err := gui.git.Patch.MovePatchIntoIndex(gui.State.Model.Commits, commitIndex, stash) err := gui.git.Patch.MovePatchIntoIndex(gui.State.Model.Commits, commitIndex, stash)
return gui.helpers.Rebase.CheckMergeOrRebase(err) return gui.helpers.MergeAndRebase.CheckMergeOrRebase(err)
}) })
} }
@ -167,7 +167,7 @@ func (gui *Gui) handlePullPatchIntoNewCommit() error {
commitIndex := gui.getPatchCommitIndex() commitIndex := gui.getPatchCommitIndex()
gui.c.LogAction(gui.c.Tr.Actions.MovePatchIntoNewCommit) gui.c.LogAction(gui.c.Tr.Actions.MovePatchIntoNewCommit)
err := gui.git.Patch.PullPatchIntoNewCommit(gui.State.Model.Commits, commitIndex) err := gui.git.Patch.PullPatchIntoNewCommit(gui.State.Model.Commits, commitIndex)
return gui.helpers.Rebase.CheckMergeOrRebase(err) return gui.helpers.MergeAndRebase.CheckMergeOrRebase(err)
}) })
} }

View File

@ -1,78 +0,0 @@
package gui
import (
"fmt"
"github.com/jesseduffield/lazygit/pkg/commands/hosting_service"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
func (gui *Gui) createPullRequestMenu(selectedBranch *models.Branch, checkedOutBranch *models.Branch) error {
menuItems := make([]*types.MenuItem, 0, 4)
fromToDisplayStrings := func(from string, to string) []string {
return []string{fmt.Sprintf("%s → %s", from, to)}
}
menuItemsForBranch := func(branch *models.Branch) []*types.MenuItem {
return []*types.MenuItem{
{
DisplayStrings: fromToDisplayStrings(branch.Name, gui.c.Tr.LcDefaultBranch),
OnPress: func() error {
return gui.createPullRequest(branch.Name, "")
},
},
{
DisplayStrings: fromToDisplayStrings(branch.Name, gui.c.Tr.LcSelectBranch),
OnPress: func() error {
return gui.c.Prompt(types.PromptOpts{
Title: branch.Name + " →",
FindSuggestionsFunc: gui.helpers.Suggestions.GetBranchNameSuggestionsFunc(),
HandleConfirm: func(targetBranchName string) error {
return gui.createPullRequest(branch.Name, targetBranchName)
}},
)
},
},
}
}
if selectedBranch != checkedOutBranch {
menuItems = append(menuItems,
&types.MenuItem{
DisplayStrings: fromToDisplayStrings(checkedOutBranch.Name, selectedBranch.Name),
OnPress: func() error {
return gui.createPullRequest(checkedOutBranch.Name, selectedBranch.Name)
},
},
)
menuItems = append(menuItems, menuItemsForBranch(checkedOutBranch)...)
}
menuItems = append(menuItems, menuItemsForBranch(selectedBranch)...)
return gui.c.Menu(types.CreateMenuOptions{Title: fmt.Sprintf(gui.c.Tr.CreatePullRequestOptions), Items: menuItems})
}
func (gui *Gui) createPullRequest(from string, to string) error {
hostingServiceMgr := gui.getHostingServiceMgr()
url, err := hostingServiceMgr.GetPullRequestURL(from, to)
if err != nil {
return gui.c.Error(err)
}
gui.c.LogAction(gui.c.Tr.Actions.OpenPullRequest)
if err := gui.os.OpenLink(url); err != nil {
return gui.c.Error(err)
}
return nil
}
func (gui *Gui) getHostingServiceMgr() *hosting_service.HostingServiceMgr {
remoteUrl := gui.git.Config.GetRemoteURL()
configServices := gui.c.UserConfig.Services
return hosting_service.NewHostingServiceMgr(gui.Log, gui.Tr, remoteUrl, configServices)
}

View File

@ -65,10 +65,9 @@ func (gui *Gui) handleViewReflogCommitFiles() error {
} }
return gui.SwitchToCommitFilesContext(controllers.SwitchToCommitFilesContextOpts{ return gui.SwitchToCommitFilesContext(controllers.SwitchToCommitFilesContextOpts{
RefName: commit.Sha, RefName: commit.Sha,
CanRebase: false, CanRebase: false,
Context: gui.State.Contexts.ReflogCommits, Context: gui.State.Contexts.ReflogCommits,
WindowName: "commits",
}) })
} }

View File

@ -215,7 +215,7 @@ func (gui *Gui) refreshCommitsWithLimit() error {
FilterPath: gui.State.Modes.Filtering.GetPath(), FilterPath: gui.State.Modes.Filtering.GetPath(),
IncludeRebaseCommits: true, IncludeRebaseCommits: true,
RefName: gui.refForLog(), RefName: gui.refForLog(),
All: gui.ShowWholeGitGraph, All: gui.State.Contexts.BranchCommits.GetShowWholeGitGraph(),
}, },
) )
if err != nil { if err != nil {
@ -408,7 +408,7 @@ func (gui *Gui) refreshStateFiles() error {
} }
if gui.git.Status.WorkingTreeState() != enums.REBASE_MODE_NONE && conflictFileCount == 0 && prevConflictFileCount > 0 { if gui.git.Status.WorkingTreeState() != enums.REBASE_MODE_NONE && conflictFileCount == 0 && prevConflictFileCount > 0 {
gui.OnUIThread(func() error { return gui.helpers.Rebase.PromptToContinueRebase() }) gui.OnUIThread(func() error { return gui.helpers.MergeAndRebase.PromptToContinueRebase() })
} }
fileTreeViewModel.RWMutex.Lock() fileTreeViewModel.RWMutex.Lock()
@ -526,7 +526,7 @@ func (gui *Gui) refreshStatus() {
gui.Mutexes.RefreshingStatusMutex.Lock() gui.Mutexes.RefreshingStatusMutex.Lock()
defer gui.Mutexes.RefreshingStatusMutex.Unlock() defer gui.Mutexes.RefreshingStatusMutex.Unlock()
currentBranch := gui.getCheckedOutBranch() currentBranch := gui.helpers.Refs.GetCheckedOutRef()
if currentBranch == nil { if currentBranch == nil {
// need to wait for branches to refresh // need to wait for branches to refresh
return return

View File

@ -34,7 +34,7 @@ func (gui *Gui) handleRemoteBranchesEscape() error {
func (gui *Gui) handleMergeRemoteBranch() error { func (gui *Gui) handleMergeRemoteBranch() error {
selectedBranchName := gui.State.Contexts.RemoteBranches.GetSelected().FullName() selectedBranchName := gui.State.Contexts.RemoteBranches.GetSelected().FullName()
return gui.mergeBranchIntoCheckedOutBranch(selectedBranchName) return gui.helpers.MergeAndRebase.MergeRefIntoCheckedOutBranch(selectedBranchName)
} }
func (gui *Gui) handleDeleteRemoteBranch() error { func (gui *Gui) handleDeleteRemoteBranch() error {
@ -63,12 +63,12 @@ func (gui *Gui) handleDeleteRemoteBranch() error {
func (gui *Gui) handleRebaseOntoRemoteBranch() error { func (gui *Gui) handleRebaseOntoRemoteBranch() error {
selectedBranchName := gui.State.Contexts.RemoteBranches.GetSelected().FullName() selectedBranchName := gui.State.Contexts.RemoteBranches.GetSelected().FullName()
return gui.handleRebaseOntoBranch(selectedBranchName) return gui.helpers.MergeAndRebase.RebaseOntoRef(selectedBranchName)
} }
func (gui *Gui) handleSetBranchUpstream() error { func (gui *Gui) handleSetBranchUpstream() error {
selectedBranch := gui.State.Contexts.RemoteBranches.GetSelected() selectedBranch := gui.State.Contexts.RemoteBranches.GetSelected()
checkedOutBranch := gui.getCheckedOutBranch() checkedOutBranch := gui.helpers.Refs.GetCheckedOutRef()
message := utils.ResolvePlaceholderString( message := utils.ResolvePlaceholderString(
gui.c.Tr.SetUpstreamMessage, gui.c.Tr.SetUpstreamMessage,
@ -101,15 +101,6 @@ func (gui *Gui) handleCreateResetToRemoteBranchMenu() error {
return gui.helpers.Refs.CreateGitResetMenu(selectedBranch.FullName()) return gui.helpers.Refs.CreateGitResetMenu(selectedBranch.FullName())
} }
func (gui *Gui) handleEnterRemoteBranch() error {
selectedBranch := gui.State.Contexts.RemoteBranches.GetSelected()
if selectedBranch == nil {
return nil
}
return gui.switchToSubCommitsContext(selectedBranch.RefName())
}
func (gui *Gui) handleNewBranchOffRemoteBranch() error { func (gui *Gui) handleNewBranchOffRemoteBranch() error {
selectedBranch := gui.State.Contexts.RemoteBranches.GetSelected() selectedBranch := gui.State.Contexts.RemoteBranches.GetSelected()
if selectedBranch == nil { if selectedBranch == nil {

View File

@ -37,8 +37,6 @@ func (gui *Gui) handleStashApply() error {
return nil return nil
} }
skipStashWarning := gui.c.UserConfig.Gui.SkipStashWarning
apply := func() error { apply := func() error {
gui.c.LogAction(gui.c.Tr.Actions.Stash) gui.c.LogAction(gui.c.Tr.Actions.Stash)
err := gui.git.Stash.Apply(stashEntry.Index) err := gui.git.Stash.Apply(stashEntry.Index)
@ -49,7 +47,7 @@ func (gui *Gui) handleStashApply() error {
return nil return nil
} }
if skipStashWarning { if gui.c.UserConfig.Gui.SkipStashWarning {
return apply() return apply()
} }
@ -68,8 +66,6 @@ func (gui *Gui) handleStashPop() error {
return nil return nil
} }
skipStashWarning := gui.c.UserConfig.Gui.SkipStashWarning
pop := func() error { pop := func() error {
gui.c.LogAction(gui.c.Tr.Actions.Stash) gui.c.LogAction(gui.c.Tr.Actions.Stash)
err := gui.git.Stash.Pop(stashEntry.Index) err := gui.git.Stash.Pop(stashEntry.Index)
@ -80,7 +76,7 @@ func (gui *Gui) handleStashPop() error {
return nil return nil
} }
if skipStashWarning { if gui.c.UserConfig.Gui.SkipStashWarning {
return pop() return pop()
} }
@ -125,10 +121,9 @@ func (gui *Gui) handleViewStashFiles() error {
} }
return gui.SwitchToCommitFilesContext(controllers.SwitchToCommitFilesContextOpts{ return gui.SwitchToCommitFilesContext(controllers.SwitchToCommitFilesContextOpts{
RefName: stashEntry.RefName(), RefName: stashEntry.RefName(),
CanRebase: false, CanRebase: false,
Context: gui.State.Contexts.Stash, Context: gui.State.Contexts.Stash,
WindowName: "stash",
}) })
} }

View File

@ -30,7 +30,7 @@ func (gui *Gui) handleCheckForUpdate() error {
func (gui *Gui) handleStatusClick() error { func (gui *Gui) handleStatusClick() error {
// TODO: move into some abstraction (status is currently not a listViewContext where a lot of this code lives) // TODO: move into some abstraction (status is currently not a listViewContext where a lot of this code lives)
currentBranch := gui.getCheckedOutBranch() currentBranch := gui.helpers.Refs.GetCheckedOutRef()
if currentBranch == nil { if currentBranch == nil {
// need to wait for branches to refresh // need to wait for branches to refresh
return nil return nil
@ -48,7 +48,7 @@ func (gui *Gui) handleStatusClick() error {
case enums.REBASE_MODE_REBASING, enums.REBASE_MODE_MERGING: case enums.REBASE_MODE_REBASING, enums.REBASE_MODE_MERGING:
workingTreeStatus := fmt.Sprintf("(%s)", formatWorkingTreeState(workingTreeState)) workingTreeStatus := fmt.Sprintf("(%s)", formatWorkingTreeState(workingTreeState))
if cursorInSubstring(cx, upstreamStatus+" ", workingTreeStatus) { if cursorInSubstring(cx, upstreamStatus+" ", workingTreeStatus) {
return gui.helpers.Rebase.CreateRebaseOptionsMenu() return gui.helpers.MergeAndRebase.CreateRebaseOptionsMenu()
} }
if cursorInSubstring(cx, upstreamStatus+" "+workingTreeStatus+" ", repoName) { if cursorInSubstring(cx, upstreamStatus+" "+workingTreeStatus+" ", repoName) {
return gui.handleCreateRecentReposMenu() return gui.handleCreateRecentReposMenu()
@ -74,7 +74,6 @@ func formatWorkingTreeState(rebaseMode enums.RebaseMode) string {
} }
func (gui *Gui) statusRenderToMain() error { func (gui *Gui) statusRenderToMain() error {
// TODO: move into some abstraction (status is currently not a listViewContext where a lot of this code lives)
dashboardString := strings.Join( dashboardString := strings.Join(
[]string{ []string{
lazygitTitle(), lazygitTitle(),
@ -114,9 +113,8 @@ func (gui *Gui) askForConfigFile(action func(file string) error) error {
} }
} }
return gui.c.Menu(types.CreateMenuOptions{ return gui.c.Menu(types.CreateMenuOptions{
Title: gui.c.Tr.SelectConfigFile, Title: gui.c.Tr.SelectConfigFile,
Items: menuItems, Items: menuItems,
HideCancel: true,
}) })
} }
} }

View File

@ -63,10 +63,9 @@ func (gui *Gui) handleViewSubCommitFiles() error {
} }
return gui.SwitchToCommitFilesContext(controllers.SwitchToCommitFilesContextOpts{ return gui.SwitchToCommitFilesContext(controllers.SwitchToCommitFilesContextOpts{
RefName: commit.Sha, RefName: commit.Sha,
CanRebase: false, CanRebase: false,
Context: gui.State.Contexts.SubCommits, Context: gui.State.Contexts.SubCommits,
WindowName: "branches",
}) })
} }

View File

@ -9,7 +9,7 @@ import (
"gopkg.in/ozeidan/fuzzy-patricia.v3/patricia" "gopkg.in/ozeidan/fuzzy-patricia.v3/patricia"
) )
type ControllerCommon struct { type HelperCommon struct {
*common.Common *common.Common
IGuiCommon IGuiCommon
} }