mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-02-01 13:17:53 +02:00
refactor controllers
This commit is contained in:
parent
b93b8cc00a
commit
722410aded
@ -1,18 +1,5 @@
|
||||
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 {
|
||||
var task updateTask
|
||||
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(), "")
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ func (gui *Gui) handleDiscardOldFileChange() error {
|
||||
return gui.c.WithWaitingStatus(gui.c.Tr.RebasingStatus, func() error {
|
||||
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.helpers.Rebase.CheckMergeOrRebase(err); err != nil {
|
||||
if err := gui.helpers.MergeAndRebase.CheckMergeOrRebase(err); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -265,7 +265,7 @@ func (gui *Gui) SwitchToCommitFilesContext(opts controllers.SwitchToCommitFilesC
|
||||
gui.State.Contexts.CommitFiles.SetRefName(opts.RefName)
|
||||
gui.State.Contexts.CommitFiles.SetCanRebase(opts.CanRebase)
|
||||
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 {
|
||||
return err
|
||||
|
@ -23,7 +23,7 @@ func NewBranchesContext(
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
) *BranchesContext {
|
||||
viewModel := NewBranchesViewModel(getModel)
|
||||
|
||||
|
@ -23,7 +23,7 @@ func NewCommitFilesContext(
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
) *CommitFilesContext {
|
||||
viewModel := filetree.NewCommitFileTreeViewModel(getModel, c.Log, c.UserConfig.Gui.ShowFileTree)
|
||||
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
type ListContextTrait struct {
|
||||
types.Context
|
||||
|
||||
c *types.ControllerCommon
|
||||
c *types.HelperCommon
|
||||
list types.IList
|
||||
viewTrait *ViewTrait
|
||||
getDisplayStrings func(startIdx int, length int) [][]string
|
||||
|
@ -23,7 +23,7 @@ func NewLocalCommitsContext(
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
) *LocalCommitsContext {
|
||||
viewModel := NewLocalCommitsViewModel(getModel)
|
||||
|
||||
@ -61,8 +61,14 @@ func (self *LocalCommitsContext) GetSelectedItemId() string {
|
||||
|
||||
type LocalCommitsViewModel struct {
|
||||
*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
|
||||
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 {
|
||||
@ -95,3 +101,11 @@ func (self *LocalCommitsViewModel) SetLimitCommits(value bool) {
|
||||
func (self *LocalCommitsViewModel) GetLimitCommits() bool {
|
||||
return self.limitCommits
|
||||
}
|
||||
|
||||
func (self *LocalCommitsViewModel) SetShowWholeGitGraph(value bool) {
|
||||
self.showWholeGitGraph = value
|
||||
}
|
||||
|
||||
func (self *LocalCommitsViewModel) GetShowWholeGitGraph() bool {
|
||||
return self.showWholeGitGraph
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ func NewMenuContext(
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
getOptionsMap func() map[string]string,
|
||||
) *MenuContext {
|
||||
viewModel := NewMenuViewModel()
|
||||
|
@ -23,7 +23,7 @@ func NewReflogCommitsContext(
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
) *ReflogCommitsContext {
|
||||
viewModel := NewReflogCommitsViewModel(getModel)
|
||||
|
||||
|
@ -23,7 +23,7 @@ func NewRemoteBranchesContext(
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
) *RemoteBranchesContext {
|
||||
viewModel := NewRemoteBranchesViewModel(getModel)
|
||||
|
||||
|
@ -23,7 +23,7 @@ func NewRemotesContext(
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
) *RemotesContext {
|
||||
viewModel := NewRemotesViewModel(getModel)
|
||||
|
||||
|
@ -23,7 +23,7 @@ func NewStashContext(
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
) *StashContext {
|
||||
viewModel := NewStashViewModel(getModel)
|
||||
|
||||
|
@ -23,7 +23,7 @@ func NewSubCommitsContext(
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
) *SubCommitsContext {
|
||||
viewModel := NewSubCommitsViewModel(getModel)
|
||||
|
||||
|
@ -23,7 +23,7 @@ func NewSubmodulesContext(
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
) *SubmodulesContext {
|
||||
viewModel := NewSubmodulesViewModel(getModel)
|
||||
|
||||
|
@ -22,7 +22,7 @@ func NewSuggestionsContext(
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
) *SuggestionsContext {
|
||||
viewModel := NewSuggestionsViewModel(getModel)
|
||||
|
||||
|
@ -23,7 +23,7 @@ func NewTagsContext(
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
) *TagsContext {
|
||||
viewModel := NewTagsViewModel(getModel)
|
||||
|
||||
|
@ -23,7 +23,7 @@ func NewWorkingTreeContext(
|
||||
onRenderToMain func(...types.OnFocusOpts) error,
|
||||
onFocusLost func() error,
|
||||
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
) *WorkingTreeContext {
|
||||
viewModel := filetree.NewFileTreeViewModel(getModel, c.Log, c.UserConfig.Gui.ShowFileTree)
|
||||
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"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/gui/context"
|
||||
@ -13,33 +12,17 @@ import (
|
||||
|
||||
type BisectController struct {
|
||||
baseController
|
||||
|
||||
c *types.ControllerCommon
|
||||
context *context.LocalCommitsContext
|
||||
git *commands.GitCommand
|
||||
bisectHelper *BisectHelper
|
||||
|
||||
getCommits func() []*models.Commit
|
||||
*controllerCommon
|
||||
}
|
||||
|
||||
var _ types.IController = &BisectController{}
|
||||
|
||||
func NewBisectController(
|
||||
c *types.ControllerCommon,
|
||||
context *context.LocalCommitsContext,
|
||||
git *commands.GitCommand,
|
||||
bisectHelper *BisectHelper,
|
||||
|
||||
getCommits func() []*models.Commit,
|
||||
common *controllerCommon,
|
||||
) *BisectController {
|
||||
return &BisectController{
|
||||
baseController: baseController{},
|
||||
c: c,
|
||||
context: context,
|
||||
git: git,
|
||||
bisectHelper: bisectHelper,
|
||||
|
||||
getCommits: getCommits,
|
||||
baseController: baseController{},
|
||||
controllerCommon: common,
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +102,7 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c
|
||||
{
|
||||
DisplayString: self.c.Tr.Bisect.ResetOption,
|
||||
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.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.bisectHelper.PostBisectCommandRefresh()
|
||||
return self.helpers.Bisect.PostBisectCommandRefresh()
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -188,7 +171,7 @@ func (self *BisectController) showBisectCompleteMessage(candidateShas []string)
|
||||
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 {
|
||||
selectFn()
|
||||
|
||||
return self.bisectHelper.PostBisectCommandRefresh()
|
||||
return self.helpers.Bisect.PostBisectCommandRefresh()
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,10 +213,10 @@ func (self *BisectController) selectCurrentBisectCommit() {
|
||||
info := self.git.Bisect.GetInfo()
|
||||
if info.GetCurrentSha() != "" {
|
||||
// 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() {
|
||||
self.context.SetSelectedLineIdx(i)
|
||||
_ = self.context.HandleFocus()
|
||||
self.context().SetSelectedLineIdx(i)
|
||||
_ = self.context().HandleFocus()
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -242,7 +225,7 @@ func (self *BisectController) selectCurrentBisectCommit() {
|
||||
|
||||
func (self *BisectController) checkSelected(callback func(*models.Commit) error) func() error {
|
||||
return func() error {
|
||||
commit := self.context.GetSelected()
|
||||
commit := self.context().GetSelected()
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
@ -252,5 +235,9 @@ func (self *BisectController) checkSelected(callback func(*models.Commit) error)
|
||||
}
|
||||
|
||||
func (self *BisectController) Context() types.Context {
|
||||
return self.context
|
||||
return self.context()
|
||||
}
|
||||
|
||||
func (self *BisectController) context() *context.LocalCommitsContext {
|
||||
return self.contexts.BranchCommits
|
||||
}
|
||||
|
475
pkg/gui/controllers/branches_controller.go
Normal file
475
pkg/gui/controllers/branches_controller.go
Normal 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)
|
||||
}
|
||||
}
|
39
pkg/gui/controllers/common.go
Normal file
39
pkg/gui/controllers/common.go
Normal 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,
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"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/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
@ -17,73 +17,33 @@ import (
|
||||
)
|
||||
|
||||
type FilesController struct {
|
||||
// I've said publicly that I'm against single-letter variable names but in this
|
||||
// case I would actually prefer a _zero_ letter variable name in the form of
|
||||
// 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
|
||||
baseController
|
||||
*controllerCommon
|
||||
|
||||
getSelectedFileNode func() *filetree.FileNode
|
||||
contexts *context.ContextTree
|
||||
enterSubmodule func(submodule *models.SubmoduleConfig) error
|
||||
getSubmodules func() []*models.SubmoduleConfig
|
||||
setCommitMessage func(message string)
|
||||
getCheckedOutBranch func() *models.Branch
|
||||
withGpgHandling func(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error
|
||||
getFailedCommitMessage func() string
|
||||
getSelectedPath func() string
|
||||
switchToMergeFn func(path string) error
|
||||
suggestionsHelper ISuggestionsHelper
|
||||
refsHelper IRefsHelper
|
||||
filesHelper IFilesHelper
|
||||
workingTreeHelper IWorkingTreeHelper
|
||||
}
|
||||
|
||||
var _ types.IController = &FilesController{}
|
||||
|
||||
func NewFilesController(
|
||||
c *types.ControllerCommon,
|
||||
context *context.WorkingTreeContext,
|
||||
model *types.Model,
|
||||
git *commands.GitCommand,
|
||||
os *oscommands.OSCommand,
|
||||
getSelectedFileNode func() *filetree.FileNode,
|
||||
allContexts *context.ContextTree,
|
||||
common *controllerCommon,
|
||||
enterSubmodule func(submodule *models.SubmoduleConfig) error,
|
||||
getSubmodules func() []*models.SubmoduleConfig,
|
||||
setCommitMessage func(message string),
|
||||
withGpgHandling func(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error,
|
||||
getFailedCommitMessage func() string,
|
||||
getSelectedPath func() string,
|
||||
switchToMergeFn func(path string) error,
|
||||
suggestionsHelper ISuggestionsHelper,
|
||||
refsHelper IRefsHelper,
|
||||
filesHelper IFilesHelper,
|
||||
workingTreeHelper IWorkingTreeHelper,
|
||||
) *FilesController {
|
||||
return &FilesController{
|
||||
c: c,
|
||||
context: context,
|
||||
model: model,
|
||||
git: git,
|
||||
os: os,
|
||||
getSelectedFileNode: getSelectedFileNode,
|
||||
contexts: allContexts,
|
||||
controllerCommon: common,
|
||||
enterSubmodule: enterSubmodule,
|
||||
getSubmodules: getSubmodules,
|
||||
setCommitMessage: setCommitMessage,
|
||||
withGpgHandling: withGpgHandling,
|
||||
getFailedCommitMessage: getFailedCommitMessage,
|
||||
getSelectedPath: getSelectedPath,
|
||||
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,
|
||||
// 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
|
||||
@ -187,6 +147,11 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
||||
Handler: self.OpenMergeTool,
|
||||
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 self.context.HandleFocus()
|
||||
return self.context().HandleFocus()
|
||||
}
|
||||
|
||||
func (self *FilesController) checkSelectedFileNode(callback func(*filetree.FileNode) error) func() error {
|
||||
return func() error {
|
||||
node := self.getSelectedFileNode()
|
||||
node := self.context().GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
@ -264,11 +229,15 @@ func (self *FilesController) checkSelectedFileNode(callback func(*filetree.FileN
|
||||
}
|
||||
|
||||
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 {
|
||||
node := self.getSelectedFileNode()
|
||||
node := self.context().GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
@ -280,7 +249,7 @@ func (self *FilesController) enter() error {
|
||||
}
|
||||
|
||||
func (self *FilesController) EnterFile(opts types.OnFocusOpts) error {
|
||||
node := self.getSelectedFileNode()
|
||||
node := self.context().GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
@ -291,7 +260,7 @@ func (self *FilesController) EnterFile(opts types.OnFocusOpts) error {
|
||||
|
||||
file := node.File
|
||||
|
||||
submoduleConfigs := self.getSubmodules()
|
||||
submoduleConfigs := self.model.Submodules
|
||||
if file.IsSubmodule(submoduleConfigs) {
|
||||
submoduleConfig := file.SubmoduleConfig(submoduleConfigs)
|
||||
return self.enterSubmodule(submoduleConfig)
|
||||
@ -410,7 +379,7 @@ func (self *FilesController) commitPrefixConfigForRepo() *config.CommitPrefixCon
|
||||
}
|
||||
|
||||
func (self *FilesController) prepareFilesForCommit() error {
|
||||
noStagedFiles := !self.workingTreeHelper.AnyStagedFiles()
|
||||
noStagedFiles := !self.helpers.WorkingTree.AnyStagedFiles()
|
||||
if noStagedFiles && self.c.UserConfig.Gui.SkipNoStagedFilesWarning {
|
||||
self.c.LogAction(self.c.Tr.Actions.StageAllFiles)
|
||||
err := self.git.WorkingTree.StageAll()
|
||||
@ -442,7 +411,7 @@ func (self *FilesController) HandleCommitPress() error {
|
||||
return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle)
|
||||
}
|
||||
|
||||
if !self.workingTreeHelper.AnyStagedFiles() {
|
||||
if !self.helpers.WorkingTree.AnyStagedFiles() {
|
||||
return self.promptToStageAllAndRetry(self.HandleCommitPress)
|
||||
}
|
||||
|
||||
@ -458,7 +427,7 @@ func (self *FilesController) HandleCommitPress() error {
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -493,7 +462,7 @@ func (self *FilesController) handleAmendCommitPress() error {
|
||||
return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle)
|
||||
}
|
||||
|
||||
if !self.workingTreeHelper.AnyStagedFiles() {
|
||||
if !self.helpers.WorkingTree.AnyStagedFiles() {
|
||||
return self.promptToStageAllAndRetry(self.handleAmendCommitPress)
|
||||
}
|
||||
|
||||
@ -519,7 +488,7 @@ func (self *FilesController) HandleCommitEditorPress() error {
|
||||
return self.c.ErrorMsg(self.c.Tr.NoFilesStagedTitle)
|
||||
}
|
||||
|
||||
if !self.workingTreeHelper.AnyStagedFiles() {
|
||||
if !self.helpers.WorkingTree.AnyStagedFiles() {
|
||||
return self.promptToStageAllAndRetry(self.HandleCommitEditorPress)
|
||||
}
|
||||
|
||||
@ -556,8 +525,8 @@ func (self *FilesController) handleStatusFilterPressed() error {
|
||||
}
|
||||
|
||||
func (self *FilesController) setStatusFiltering(filter filetree.FileTreeDisplayFilter) error {
|
||||
self.context.FileTreeViewModel.SetFilter(filter)
|
||||
return self.c.PostRefreshUpdate(self.context)
|
||||
self.context().FileTreeViewModel.SetFilter(filter)
|
||||
return self.c.PostRefreshUpdate(self.context())
|
||||
}
|
||||
|
||||
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.filesHelper.EditFile(node.GetPath())
|
||||
return self.helpers.Files.EditFile(node.GetPath())
|
||||
}
|
||||
|
||||
func (self *FilesController) Open() error {
|
||||
node := self.getSelectedFileNode()
|
||||
node := self.context().GetSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.filesHelper.OpenFile(node.GetPath())
|
||||
return self.helpers.Files.OpenFile(node.GetPath())
|
||||
}
|
||||
|
||||
func (self *FilesController) switchToMerge() error {
|
||||
@ -613,16 +582,16 @@ func (self *FilesController) stash() error {
|
||||
}
|
||||
|
||||
func (self *FilesController) createResetMenu() error {
|
||||
return self.refsHelper.CreateGitResetMenu("@{upstream}")
|
||||
return self.helpers.Refs.CreateGitResetMenu("@{upstream}")
|
||||
}
|
||||
|
||||
func (self *FilesController) handleToggleDirCollapsed() error {
|
||||
node := self.getSelectedFileNode()
|
||||
node := self.context().GetSelectedFileNode()
|
||||
if node == 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 {
|
||||
self.c.Log.Error(err)
|
||||
@ -632,9 +601,9 @@ func (self *FilesController) handleToggleDirCollapsed() 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 {
|
||||
@ -654,7 +623,7 @@ func (self *FilesController) ResetSubmodule(submodule *models.SubmoduleConfig) e
|
||||
return self.c.WithWaitingStatus(self.c.Tr.LcResettingSubmoduleStatus, func() error {
|
||||
self.c.LogAction(self.c.Tr.Actions.ResetSubmodule)
|
||||
|
||||
file := self.workingTreeHelper.FileForSubmodule(submodule)
|
||||
file := self.helpers.WorkingTree.FileForSubmodule(submodule)
|
||||
if file != nil {
|
||||
if err := self.git.WorkingTree.UnStageFile(file.Names(), file.Tracked); err != nil {
|
||||
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 {
|
||||
if !self.workingTreeHelper.IsWorkingTreeDirty() {
|
||||
if !self.helpers.WorkingTree.IsWorkingTreeDirty() {
|
||||
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
|
||||
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
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ func (self *FilesController) remove(node *filetree.FileNode) error {
|
||||
} else {
|
||||
file := node.File
|
||||
|
||||
submodules := self.getSubmodules()
|
||||
submodules := self.model.Submodules
|
||||
if file.IsSubmodule(submodules) {
|
||||
submodule := file.SubmoduleConfig(submodules)
|
||||
|
||||
|
@ -1,26 +1,22 @@
|
||||
package controllers
|
||||
|
||||
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/utils"
|
||||
)
|
||||
|
||||
type GlobalController struct {
|
||||
baseController
|
||||
|
||||
c *types.ControllerCommon
|
||||
os *oscommands.OSCommand
|
||||
*controllerCommon
|
||||
}
|
||||
|
||||
func NewGlobalController(
|
||||
c *types.ControllerCommon,
|
||||
os *oscommands.OSCommand,
|
||||
common *controllerCommon,
|
||||
) *GlobalController {
|
||||
return &GlobalController{
|
||||
baseController: baseController{},
|
||||
c: c,
|
||||
os: os,
|
||||
baseController: baseController{},
|
||||
controllerCommon: common,
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,7 +59,7 @@ func (self *GlobalController) GetCustomCommandsHistorySuggestionsFunc() func(str
|
||||
// reversing so that we display the latest command first
|
||||
history := utils.Reverse(self.c.GetAppState().CustomCommandsHistory)
|
||||
|
||||
return FuzzySearchFunc(history)
|
||||
return helpers.FuzzySearchFunc(history)
|
||||
}
|
||||
|
||||
func (self *GlobalController) Context() types.Context {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
@ -6,12 +6,12 @@ import (
|
||||
)
|
||||
|
||||
type BisectHelper struct {
|
||||
c *types.ControllerCommon
|
||||
c *types.HelperCommon
|
||||
git *commands.GitCommand
|
||||
}
|
||||
|
||||
func NewBisectHelper(
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
git *commands.GitCommand,
|
||||
) *BisectHelper {
|
||||
return &BisectHelper{
|
@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
@ -9,25 +9,25 @@ import (
|
||||
)
|
||||
|
||||
type CherryPickHelper struct {
|
||||
c *types.ControllerCommon
|
||||
c *types.HelperCommon
|
||||
|
||||
git *commands.GitCommand
|
||||
|
||||
contexts *context.ContextTree
|
||||
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,
|
||||
// even if in truth we're running git cherry-pick
|
||||
|
||||
func NewCherryPickHelper(
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
git *commands.GitCommand,
|
||||
contexts *context.ContextTree,
|
||||
getData func() *cherrypicking.CherryPicking,
|
||||
rebaseHelper *RebaseHelper,
|
||||
rebaseHelper *MergeAndRebaseHelper,
|
||||
) *CherryPickHelper {
|
||||
return &CherryPickHelper{
|
||||
c: c,
|
@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
@ -14,13 +14,13 @@ type IFilesHelper interface {
|
||||
}
|
||||
|
||||
type FilesHelper struct {
|
||||
c *types.ControllerCommon
|
||||
c *types.HelperCommon
|
||||
git *commands.GitCommand
|
||||
os *oscommands.OSCommand
|
||||
}
|
||||
|
||||
func NewFilesHelper(
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
git *commands.GitCommand,
|
||||
os *oscommands.OSCommand,
|
||||
) *FilesHelper {
|
13
pkg/gui/controllers/helpers/helpers.go
Normal file
13
pkg/gui/controllers/helpers/helpers.go
Normal 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
|
||||
}
|
46
pkg/gui/controllers/helpers/host_helper.go
Normal file
46
pkg/gui/controllers/helpers/host_helper.go
Normal 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)
|
||||
}
|
@ -1,33 +1,38 @@
|
||||
package controllers
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"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/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
type RebaseHelper struct {
|
||||
c *types.ControllerCommon
|
||||
type MergeAndRebaseHelper struct {
|
||||
c *types.HelperCommon
|
||||
contexts *context.ContextTree
|
||||
git *commands.GitCommand
|
||||
takeOverMergeConflictScrolling func()
|
||||
refsHelper *RefsHelper
|
||||
}
|
||||
|
||||
func NewRebaseHelper(
|
||||
c *types.ControllerCommon,
|
||||
func NewMergeAndRebaseHelper(
|
||||
c *types.HelperCommon,
|
||||
contexts *context.ContextTree,
|
||||
git *commands.GitCommand,
|
||||
takeOverMergeConflictScrolling func(),
|
||||
) *RebaseHelper {
|
||||
return &RebaseHelper{
|
||||
refsHelper *RefsHelper,
|
||||
) *MergeAndRebaseHelper {
|
||||
return &MergeAndRebaseHelper{
|
||||
c: c,
|
||||
contexts: contexts,
|
||||
git: git,
|
||||
takeOverMergeConflictScrolling: takeOverMergeConflictScrolling,
|
||||
refsHelper: refsHelper,
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,7 +44,7 @@ const (
|
||||
REBASE_OPTION_SKIP string = "skip"
|
||||
)
|
||||
|
||||
func (self *RebaseHelper) CreateRebaseOptionsMenu() error {
|
||||
func (self *MergeAndRebaseHelper) CreateRebaseOptionsMenu() error {
|
||||
options := []string{REBASE_OPTION_CONTINUE, REBASE_OPTION_ABORT}
|
||||
|
||||
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})
|
||||
}
|
||||
|
||||
func (self *RebaseHelper) genericMergeCommand(command string) error {
|
||||
func (self *MergeAndRebaseHelper) genericMergeCommand(command string) error {
|
||||
status := self.git.Status.WorkingTreeState()
|
||||
|
||||
if status != enums.REBASE_MODE_MERGING && status != enums.REBASE_MODE_REBASING {
|
||||
@ -120,7 +125,7 @@ func isMergeConflictErr(errStr string) bool {
|
||||
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 {
|
||||
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
|
||||
mode := self.workingTreeStateNoun()
|
||||
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()
|
||||
switch workingTreeState {
|
||||
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
|
||||
func (self *RebaseHelper) PromptToContinueRebase() error {
|
||||
func (self *MergeAndRebaseHelper) PromptToContinueRebase() error {
|
||||
self.takeOverMergeConflictScrolling()
|
||||
|
||||
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)
|
||||
},
|
||||
})
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -6,6 +6,7 @@ import (
|
||||
|
||||
"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/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
@ -14,26 +15,30 @@ import (
|
||||
|
||||
type IRefsHelper interface {
|
||||
CheckoutRef(ref string, options types.CheckoutRefOptions) error
|
||||
GetCheckedOutRef() *models.Branch
|
||||
CreateGitResetMenu(ref string) error
|
||||
ResetToRef(ref string, strength string, envVars []string) error
|
||||
NewBranch(from string, fromDescription string, suggestedBranchname string) error
|
||||
}
|
||||
|
||||
type RefsHelper struct {
|
||||
c *types.ControllerCommon
|
||||
c *types.HelperCommon
|
||||
git *commands.GitCommand
|
||||
contexts *context.ContextTree
|
||||
model *types.Model
|
||||
}
|
||||
|
||||
func NewRefsHelper(
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
git *commands.GitCommand,
|
||||
contexts *context.ContextTree,
|
||||
model *types.Model,
|
||||
) *RefsHelper {
|
||||
return &RefsHelper{
|
||||
c: c,
|
||||
git: git,
|
||||
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 {
|
||||
if err := self.git.Commit.ResetToCommit(ref, strength, envVars); err != nil {
|
||||
return self.c.Error(err)
|
@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -30,7 +30,7 @@ type ISuggestionsHelper interface {
|
||||
}
|
||||
|
||||
type SuggestionsHelper struct {
|
||||
c *types.ControllerCommon
|
||||
c *types.HelperCommon
|
||||
|
||||
model *types.Model
|
||||
refreshSuggestionsFn func()
|
||||
@ -39,7 +39,7 @@ type SuggestionsHelper struct {
|
||||
var _ ISuggestionsHelper = &SuggestionsHelper{}
|
||||
|
||||
func NewSuggestionsHelper(
|
||||
c *types.ControllerCommon,
|
||||
c *types.HelperCommon,
|
||||
model *types.Model,
|
||||
refreshSuggestionsFn func(),
|
||||
) *SuggestionsHelper {
|
@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
@ -10,11 +10,11 @@ import (
|
||||
// and the commits context.
|
||||
|
||||
type TagsHelper struct {
|
||||
c *types.ControllerCommon
|
||||
c *types.HelperCommon
|
||||
git *commands.GitCommand
|
||||
}
|
||||
|
||||
func NewTagsHelper(c *types.ControllerCommon, git *commands.GitCommand) *TagsHelper {
|
||||
func NewTagsHelper(c *types.HelperCommon, git *commands.GitCommand) *TagsHelper {
|
||||
return &TagsHelper{
|
||||
c: c,
|
||||
git: git,
|
@ -1,4 +1,4 @@
|
||||
package controllers
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
@ -6,10 +6,10 @@ import (
|
||||
)
|
||||
|
||||
type ListControllerFactory struct {
|
||||
c *types.ControllerCommon
|
||||
c *types.HelperCommon
|
||||
}
|
||||
|
||||
func NewListControllerFactory(c *types.ControllerCommon) *ListControllerFactory {
|
||||
func NewListControllerFactory(c *types.HelperCommon) *ListControllerFactory {
|
||||
return &ListControllerFactory{
|
||||
c: c,
|
||||
}
|
||||
@ -25,7 +25,7 @@ func (self *ListControllerFactory) Create(context types.IListContext) *ListContr
|
||||
|
||||
type ListController struct {
|
||||
baseController
|
||||
c *types.ControllerCommon
|
||||
c *types.HelperCommon
|
||||
|
||||
context types.IListContext
|
||||
}
|
||||
|
@ -4,80 +4,37 @@ import (
|
||||
"fmt"
|
||||
|
||||
"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/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
type (
|
||||
CheckoutRefFn func(refName string, opts types.CheckoutRefOptions) error
|
||||
CreateGitResetMenuFn func(refName string) error
|
||||
SwitchToCommitFilesContextFn func(SwitchToCommitFilesContextOpts) error
|
||||
GetHostingServiceMgrFn func() *hosting_service.HostingServiceMgr
|
||||
PullFilesFn func() error
|
||||
CheckMergeOrRebase func(error) error
|
||||
)
|
||||
|
||||
type LocalCommitsController struct {
|
||||
baseController
|
||||
c *types.ControllerCommon
|
||||
context *context.LocalCommitsContext
|
||||
os *oscommands.OSCommand
|
||||
git *commands.GitCommand
|
||||
tagsHelper *TagsHelper
|
||||
refsHelper IRefsHelper
|
||||
cherryPickHelper *CherryPickHelper
|
||||
rebaseHelper *RebaseHelper
|
||||
*controllerCommon
|
||||
|
||||
model *types.Model
|
||||
CheckMergeOrRebase CheckMergeOrRebase
|
||||
pullFiles PullFilesFn
|
||||
getHostingServiceMgr GetHostingServiceMgrFn
|
||||
switchToCommitFilesContext SwitchToCommitFilesContextFn
|
||||
getShowWholeGitGraph func() bool
|
||||
setShowWholeGitGraph func(bool)
|
||||
}
|
||||
|
||||
var _ types.IController = &LocalCommitsController{}
|
||||
|
||||
func NewLocalCommitsController(
|
||||
c *types.ControllerCommon,
|
||||
context *context.LocalCommitsContext,
|
||||
os *oscommands.OSCommand,
|
||||
git *commands.GitCommand,
|
||||
tagsHelper *TagsHelper,
|
||||
refsHelper IRefsHelper,
|
||||
cherryPickHelper *CherryPickHelper,
|
||||
rebaseHelper *RebaseHelper,
|
||||
model *types.Model,
|
||||
CheckMergeOrRebase CheckMergeOrRebase,
|
||||
common *controllerCommon,
|
||||
pullFiles PullFilesFn,
|
||||
getHostingServiceMgr GetHostingServiceMgrFn,
|
||||
switchToCommitFilesContext SwitchToCommitFilesContextFn,
|
||||
getShowWholeGitGraph func() bool,
|
||||
setShowWholeGitGraph func(bool),
|
||||
) *LocalCommitsController {
|
||||
return &LocalCommitsController{
|
||||
baseController: baseController{},
|
||||
c: c,
|
||||
context: context,
|
||||
os: os,
|
||||
git: git,
|
||||
tagsHelper: tagsHelper,
|
||||
refsHelper: refsHelper,
|
||||
cherryPickHelper: cherryPickHelper,
|
||||
rebaseHelper: rebaseHelper,
|
||||
model: model,
|
||||
CheckMergeOrRebase: CheckMergeOrRebase,
|
||||
controllerCommon: common,
|
||||
pullFiles: pullFiles,
|
||||
getHostingServiceMgr: getHostingServiceMgr,
|
||||
switchToCommitFilesContext: switchToCommitFilesContext,
|
||||
getShowWholeGitGraph: getShowWholeGitGraph,
|
||||
setShowWholeGitGraph: setShowWholeGitGraph,
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,7 +142,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
||||
},
|
||||
// {
|
||||
// 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,
|
||||
HandleConfirm: func(response string) error {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -325,7 +282,7 @@ func (self *LocalCommitsController) rewordEditor() error {
|
||||
|
||||
self.c.LogAction(self.c.Tr.Actions.RewordCommit)
|
||||
subProcess, err := self.git.Rebase.RewordCommitInEditor(
|
||||
self.model.Commits, self.context.GetSelectedLineIdx(),
|
||||
self.model.Commits, self.context().GetSelectedLineIdx(),
|
||||
)
|
||||
if err != nil {
|
||||
return self.c.Error(err)
|
||||
@ -388,15 +345,15 @@ func (self *LocalCommitsController) pick() error {
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) interactiveRebase(action string) error {
|
||||
err := self.git.Rebase.InteractiveRebase(self.model.Commits, self.context.GetSelectedLineIdx(), action)
|
||||
return self.CheckMergeOrRebase(err)
|
||||
err := self.git.Rebase.InteractiveRebase(self.model.Commits, self.context().GetSelectedLineIdx(), action)
|
||||
return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
|
||||
}
|
||||
|
||||
// handleMidRebaseCommand sees if the selected commit is in fact a rebasing
|
||||
// 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
|
||||
func (self *LocalCommitsController) handleMidRebaseCommand(action string) (bool, error) {
|
||||
selectedCommit := self.context.GetSelected()
|
||||
selectedCommit := self.context().GetSelected()
|
||||
if selectedCommit.Status != "rebasing" {
|
||||
return false, nil
|
||||
}
|
||||
@ -416,7 +373,7 @@ func (self *LocalCommitsController) handleMidRebaseCommand(action string) (bool,
|
||||
)
|
||||
|
||||
if err := self.git.Rebase.EditRebaseTodo(
|
||||
self.context.GetSelectedLineIdx(), action,
|
||||
self.context().GetSelectedLineIdx(), action,
|
||||
); err != nil {
|
||||
return false, self.c.Error(err)
|
||||
}
|
||||
@ -427,7 +384,7 @@ func (self *LocalCommitsController) handleMidRebaseCommand(action string) (bool,
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) handleCommitMoveDown() error {
|
||||
index := self.context.GetSelectedLineIdx()
|
||||
index := self.context().GetSelectedLineIdx()
|
||||
commits := self.model.Commits
|
||||
selectedCommit := self.model.Commits[index]
|
||||
if selectedCommit.Status == "rebasing" {
|
||||
@ -443,7 +400,7 @@ func (self *LocalCommitsController) handleCommitMoveDown() error {
|
||||
if err := self.git.Rebase.MoveTodoDown(index); err != nil {
|
||||
return self.c.Error(err)
|
||||
}
|
||||
self.context.MoveSelectedLine(1)
|
||||
self.context().MoveSelectedLine(1)
|
||||
return self.c.Refresh(types.RefreshOptions{
|
||||
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)
|
||||
err := self.git.Rebase.MoveCommitDown(self.model.Commits, index)
|
||||
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 {
|
||||
index := self.context.GetSelectedLineIdx()
|
||||
index := self.context().GetSelectedLineIdx()
|
||||
if index == 0 {
|
||||
return nil
|
||||
}
|
||||
@ -478,7 +435,7 @@ func (self *LocalCommitsController) handleCommitMoveUp() error {
|
||||
if err := self.git.Rebase.MoveTodoDown(index - 1); err != nil {
|
||||
return self.c.Error(err)
|
||||
}
|
||||
self.context.MoveSelectedLine(-1)
|
||||
self.context().MoveSelectedLine(-1)
|
||||
return self.c.Refresh(types.RefreshOptions{
|
||||
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)
|
||||
err := self.git.Rebase.MoveCommitDown(self.model.Commits, index-1)
|
||||
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 {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func() error {
|
||||
self.c.LogAction(self.c.Tr.Actions.AmendCommit)
|
||||
err := self.git.Rebase.AmendTo(self.context.GetSelected().Sha)
|
||||
return self.CheckMergeOrRebase(err)
|
||||
err := self.git.Rebase.AmendTo(self.context().GetSelected().Sha)
|
||||
return self.helpers.MergeAndRebase.CheckMergeOrRebase(err)
|
||||
})
|
||||
},
|
||||
})
|
||||
@ -556,7 +513,7 @@ func (self *LocalCommitsController) createRevertMergeCommitMenu(commit *models.C
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) afterRevertCommit() error {
|
||||
self.context.MoveSelectedLine(1)
|
||||
self.context().MoveSelectedLine(1)
|
||||
return self.c.Refresh(types.RefreshOptions{
|
||||
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 {
|
||||
return self.switchToCommitFilesContext(SwitchToCommitFilesContextOpts{
|
||||
RefName: commit.Sha,
|
||||
CanRebase: true,
|
||||
Context: self.context,
|
||||
WindowName: "commits",
|
||||
RefName: commit.Sha,
|
||||
CanRebase: true,
|
||||
Context: self.context(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -608,14 +564,14 @@ func (self *LocalCommitsController) handleSquashAllAboveFixupCommits(commit *mod
|
||||
return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func() error {
|
||||
self.c.LogAction(self.c.Tr.Actions.SquashAllAboveFixupCommits)
|
||||
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 {
|
||||
return self.tagsHelper.CreateTagMenu(commit.Sha, func() {})
|
||||
return self.helpers.Tags.CreateTagMenu(commit.Sha, func() {})
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) handleCheckoutCommit(commit *models.Commit) error {
|
||||
@ -624,19 +580,19 @@ func (self *LocalCommitsController) handleCheckoutCommit(commit *models.Commit)
|
||||
Prompt: self.c.Tr.SureCheckoutThisCommit,
|
||||
HandleConfirm: func() error {
|
||||
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 {
|
||||
return self.refsHelper.CreateGitResetMenu(commit.Sha)
|
||||
return self.helpers.Refs.CreateGitResetMenu(commit.Sha)
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) openSearch() error {
|
||||
// we usually lazyload these commits but now that we're searching we need to load them now
|
||||
if self.context.GetLimitCommits() {
|
||||
self.context.SetLimitCommits(false)
|
||||
if self.context().GetLimitCommits() {
|
||||
self.context().SetLimitCommits(false)
|
||||
if err := self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.COMMITS}}); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -649,14 +605,14 @@ func (self *LocalCommitsController) openSearch() 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
|
||||
if self.context.GetLimitCommits() {
|
||||
self.context.SetLimitCommits(false)
|
||||
if self.context().GetLimitCommits() {
|
||||
self.context().SetLimitCommits(false)
|
||||
if err := self.c.Refresh(types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{types.COMMITS}}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
self.context.SetSelectedLineIdx(self.context.GetItemsLength() - 1)
|
||||
self.context().SetSelectedLineIdx(self.context().GetItemsLength() - 1)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -684,10 +640,10 @@ func (self *LocalCommitsController) handleOpenLogMenu() error {
|
||||
{
|
||||
DisplayString: self.c.Tr.ToggleShowGitGraphAll,
|
||||
OnPress: func() error {
|
||||
self.setShowWholeGitGraph(!self.getShowWholeGitGraph())
|
||||
self.context().SetShowWholeGitGraph(!self.context().GetShowWholeGitGraph())
|
||||
|
||||
if self.getShowWholeGitGraph() {
|
||||
self.context.SetLimitCommits(false)
|
||||
if self.context().GetShowWholeGitGraph() {
|
||||
self.context().SetLimitCommits(false)
|
||||
}
|
||||
|
||||
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 {
|
||||
hostingServiceMgr := self.getHostingServiceMgr()
|
||||
|
||||
url, err := hostingServiceMgr.GetCommitURL(commit.Sha)
|
||||
url, err := self.helpers.Host.GetCommitURL(commit.Sha)
|
||||
if err != nil {
|
||||
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 {
|
||||
return func() error {
|
||||
commit := self.context.GetSelected()
|
||||
commit := self.context().GetSelected()
|
||||
if commit == nil {
|
||||
return nil
|
||||
}
|
||||
@ -788,21 +742,25 @@ func (self *LocalCommitsController) checkSelected(callback func(*models.Commit)
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
return self.cherryPickHelper.Paste()
|
||||
return self.helpers.CherryPick.Paste()
|
||||
}
|
||||
|
@ -7,22 +7,17 @@ import (
|
||||
|
||||
type MenuController struct {
|
||||
baseController
|
||||
|
||||
c *types.ControllerCommon
|
||||
context *context.MenuContext
|
||||
*controllerCommon
|
||||
}
|
||||
|
||||
var _ types.IController = &MenuController{}
|
||||
|
||||
func NewMenuController(
|
||||
c *types.ControllerCommon,
|
||||
context *context.MenuContext,
|
||||
common *controllerCommon,
|
||||
) *MenuController {
|
||||
return &MenuController{
|
||||
baseController: baseController{},
|
||||
|
||||
c: c,
|
||||
context: context,
|
||||
baseController: baseController{},
|
||||
controllerCommon: common,
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,7 +45,7 @@ func (self *MenuController) GetKeybindings(opts types.KeybindingsOpts) []*types.
|
||||
}
|
||||
|
||||
func (self *MenuController) press() error {
|
||||
selectedItem := self.context.GetSelected()
|
||||
selectedItem := self.context().GetSelected()
|
||||
|
||||
if err := self.c.PopContext(); err != nil {
|
||||
return err
|
||||
@ -64,5 +59,9 @@ func (self *MenuController) press() error {
|
||||
}
|
||||
|
||||
func (self *MenuController) Context() types.Context {
|
||||
return self.context
|
||||
return self.context()
|
||||
}
|
||||
|
||||
func (self *MenuController) context() *context.MenuContext {
|
||||
return self.contexts.Menu
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
@ -10,30 +9,22 @@ import (
|
||||
|
||||
type RemotesController struct {
|
||||
baseController
|
||||
|
||||
c *types.ControllerCommon
|
||||
*controllerCommon
|
||||
context *context.RemotesContext
|
||||
git *commands.GitCommand
|
||||
|
||||
setRemoteBranches func([]*models.RemoteBranch)
|
||||
contexts *context.ContextTree
|
||||
}
|
||||
|
||||
var _ types.IController = &RemotesController{}
|
||||
|
||||
func NewRemotesController(
|
||||
c *types.ControllerCommon,
|
||||
context *context.RemotesContext,
|
||||
git *commands.GitCommand,
|
||||
contexts *context.ContextTree,
|
||||
common *controllerCommon,
|
||||
setRemoteBranches func([]*models.RemoteBranch),
|
||||
) *RemotesController {
|
||||
return &RemotesController{
|
||||
baseController: baseController{},
|
||||
c: c,
|
||||
git: git,
|
||||
contexts: contexts,
|
||||
context: context,
|
||||
controllerCommon: common,
|
||||
context: common.contexts.Remotes,
|
||||
setRemoteBranches: setRemoteBranches,
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,14 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/loaders"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
)
|
||||
|
||||
type SubCommitsSwitchControllerFactory struct {
|
||||
c *types.ControllerCommon
|
||||
subCommitsContext *context.SubCommitsContext
|
||||
git *commands.GitCommand
|
||||
modes *types.Modes
|
||||
setSubCommits func([]*models.Commit)
|
||||
controllerCommon *controllerCommon
|
||||
setSubCommits func([]*models.Commit)
|
||||
}
|
||||
|
||||
var _ types.IController = &SubCommitsSwitchController{}
|
||||
@ -25,40 +20,28 @@ type ContextWithRefName interface {
|
||||
|
||||
type SubCommitsSwitchController struct {
|
||||
baseController
|
||||
*controllerCommon
|
||||
context ContextWithRefName
|
||||
|
||||
c *types.ControllerCommon
|
||||
context ContextWithRefName
|
||||
subCommitsContext *context.SubCommitsContext
|
||||
git *commands.GitCommand
|
||||
modes *types.Modes
|
||||
setSubCommits func([]*models.Commit)
|
||||
setSubCommits func([]*models.Commit)
|
||||
}
|
||||
|
||||
func NewSubCommitsSwitchControllerFactory(
|
||||
c *types.ControllerCommon,
|
||||
subCommitsContext *context.SubCommitsContext,
|
||||
git *commands.GitCommand,
|
||||
modes *types.Modes,
|
||||
common *controllerCommon,
|
||||
setSubCommits func([]*models.Commit),
|
||||
) *SubCommitsSwitchControllerFactory {
|
||||
return &SubCommitsSwitchControllerFactory{
|
||||
c: c,
|
||||
subCommitsContext: subCommitsContext,
|
||||
git: git,
|
||||
modes: modes,
|
||||
setSubCommits: setSubCommits,
|
||||
controllerCommon: common,
|
||||
setSubCommits: setSubCommits,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SubCommitsSwitchControllerFactory) Create(context ContextWithRefName) *SubCommitsSwitchController {
|
||||
return &SubCommitsSwitchController{
|
||||
baseController: baseController{},
|
||||
c: self.c,
|
||||
context: context,
|
||||
subCommitsContext: self.subCommitsContext,
|
||||
git: self.git,
|
||||
modes: self.modes,
|
||||
setSubCommits: self.setSubCommits,
|
||||
baseController: baseController{},
|
||||
controllerCommon: self.controllerCommon,
|
||||
context: context,
|
||||
setSubCommits: self.setSubCommits,
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,10 +77,10 @@ func (self *SubCommitsSwitchController) viewCommits() error {
|
||||
}
|
||||
|
||||
self.setSubCommits(commits)
|
||||
self.subCommitsContext.SetSelectedLineIdx(0)
|
||||
self.subCommitsContext.SetParentContext(self.context)
|
||||
self.contexts.SubCommits.SetSelectedLineIdx(0)
|
||||
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 {
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
@ -14,10 +13,7 @@ import (
|
||||
|
||||
type SubmodulesController struct {
|
||||
baseController
|
||||
|
||||
c *types.ControllerCommon
|
||||
context *context.SubmodulesContext
|
||||
git *commands.GitCommand
|
||||
*controllerCommon
|
||||
|
||||
enterSubmodule func(submodule *models.SubmoduleConfig) error
|
||||
}
|
||||
@ -25,17 +21,13 @@ type SubmodulesController struct {
|
||||
var _ types.IController = &SubmodulesController{}
|
||||
|
||||
func NewSubmodulesController(
|
||||
c *types.ControllerCommon,
|
||||
context *context.SubmodulesContext,
|
||||
git *commands.GitCommand,
|
||||
controllerCommon *controllerCommon,
|
||||
enterSubmodule func(submodule *models.SubmoduleConfig) error,
|
||||
) *SubmodulesController {
|
||||
return &SubmodulesController{
|
||||
baseController: baseController{},
|
||||
c: c,
|
||||
context: context,
|
||||
git: git,
|
||||
enterSubmodule: enterSubmodule,
|
||||
baseController: baseController{},
|
||||
controllerCommon: controllerCommon,
|
||||
enterSubmodule: enterSubmodule,
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +71,7 @@ func (self *SubmodulesController) GetKeybindings(opts types.KeybindingsOpts) []*
|
||||
},
|
||||
// {
|
||||
// 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 {
|
||||
return func() error {
|
||||
submodule := self.context.GetSelected()
|
||||
submodule := self.context().GetSelected()
|
||||
if submodule == nil {
|
||||
return nil
|
||||
}
|
||||
@ -237,5 +229,9 @@ func (self *SubmodulesController) checkSelected(callback func(*models.SubmoduleC
|
||||
}
|
||||
|
||||
func (self *SubmodulesController) Context() types.Context {
|
||||
return self.context
|
||||
return self.context()
|
||||
}
|
||||
|
||||
func (self *SubmodulesController) context() *context.SubmodulesContext {
|
||||
return self.contexts.Submodules
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"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/gui/types"
|
||||
@ -12,35 +11,22 @@ import (
|
||||
|
||||
type SyncController struct {
|
||||
baseController
|
||||
*controllerCommon
|
||||
|
||||
c *types.ControllerCommon
|
||||
git *commands.GitCommand
|
||||
|
||||
getCheckedOutBranch func() *models.Branch
|
||||
suggestionsHelper ISuggestionsHelper
|
||||
getSuggestedRemote func() string
|
||||
CheckMergeOrRebase func(error) error
|
||||
getSuggestedRemote func() string
|
||||
}
|
||||
|
||||
var _ types.IController = &SyncController{}
|
||||
|
||||
func NewSyncController(
|
||||
c *types.ControllerCommon,
|
||||
git *commands.GitCommand,
|
||||
getCheckedOutBranch func() *models.Branch,
|
||||
suggestionsHelper ISuggestionsHelper,
|
||||
common *controllerCommon,
|
||||
getSuggestedRemote func() string,
|
||||
CheckMergeOrRebase func(error) error,
|
||||
) *SyncController {
|
||||
return &SyncController{
|
||||
baseController: baseController{},
|
||||
c: c,
|
||||
git: git,
|
||||
baseController: baseController{},
|
||||
controllerCommon: common,
|
||||
|
||||
getCheckedOutBranch: getCheckedOutBranch,
|
||||
suggestionsHelper: suggestionsHelper,
|
||||
getSuggestedRemote: getSuggestedRemote,
|
||||
CheckMergeOrRebase: CheckMergeOrRebase,
|
||||
getSuggestedRemote: getSuggestedRemote,
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +61,7 @@ func (self *SyncController) HandlePull() error {
|
||||
|
||||
func (self *SyncController) branchCheckedOut(f func(*models.Branch) error) func() error {
|
||||
return func() error {
|
||||
currentBranch := self.getCheckedOutBranch()
|
||||
currentBranch := self.helpers.Refs.GetCheckedOutRef()
|
||||
if currentBranch == nil {
|
||||
// need to wait for branches to refresh
|
||||
return nil
|
||||
@ -160,7 +146,7 @@ func (self *SyncController) promptForUpstream(currentBranch *models.Branch, onCo
|
||||
return self.c.Prompt(types.PromptOpts{
|
||||
Title: self.c.Tr.EnterUpstream,
|
||||
InitialContent: suggestedRemote + " " + currentBranch.Name,
|
||||
FindSuggestionsFunc: self.suggestionsHelper.GetRemoteBranchesSuggestionsFunc(" "),
|
||||
FindSuggestionsFunc: self.helpers.Suggestions.GetRemoteBranchesSuggestionsFunc(" "),
|
||||
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 {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
@ -10,43 +9,17 @@ import (
|
||||
|
||||
type TagsController struct {
|
||||
baseController
|
||||
|
||||
c *types.ControllerCommon
|
||||
context *context.TagsContext
|
||||
git *commands.GitCommand
|
||||
contexts *context.ContextTree
|
||||
tagsHelper *TagsHelper
|
||||
|
||||
refsHelper IRefsHelper
|
||||
suggestionsHelper ISuggestionsHelper
|
||||
|
||||
switchToSubCommitsContext func(string) error
|
||||
*controllerCommon
|
||||
}
|
||||
|
||||
var _ types.IController = &TagsController{}
|
||||
|
||||
func NewTagsController(
|
||||
c *types.ControllerCommon,
|
||||
context *context.TagsContext,
|
||||
git *commands.GitCommand,
|
||||
contexts *context.ContextTree,
|
||||
tagsHelper *TagsHelper,
|
||||
refsHelper IRefsHelper,
|
||||
suggestionsHelper ISuggestionsHelper,
|
||||
|
||||
switchToSubCommitsContext func(string) error,
|
||||
common *controllerCommon,
|
||||
) *TagsController {
|
||||
return &TagsController{
|
||||
baseController: baseController{},
|
||||
c: c,
|
||||
context: context,
|
||||
git: git,
|
||||
contexts: contexts,
|
||||
tagsHelper: tagsHelper,
|
||||
refsHelper: refsHelper,
|
||||
suggestionsHelper: suggestionsHelper,
|
||||
|
||||
switchToSubCommitsContext: switchToSubCommitsContext,
|
||||
baseController: baseController{},
|
||||
controllerCommon: common,
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,7 +58,7 @@ func (self *TagsController) GetKeybindings(opts types.KeybindingsOpts) []*types.
|
||||
|
||||
func (self *TagsController) checkout(tag *models.Tag) error {
|
||||
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 self.c.PushContext(self.contexts.Branches)
|
||||
@ -123,7 +96,7 @@ func (self *TagsController) push(tag *models.Tag) error {
|
||||
return self.c.Prompt(types.PromptOpts{
|
||||
Title: title,
|
||||
InitialContent: "origin",
|
||||
FindSuggestionsFunc: self.suggestionsHelper.GetRemoteSuggestionsFunc(),
|
||||
FindSuggestionsFunc: self.helpers.Suggestions.GetRemoteSuggestionsFunc(),
|
||||
HandleConfirm: func(response string) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.PushingTagStatus, func() error {
|
||||
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 {
|
||||
return self.refsHelper.CreateGitResetMenu(tag.Name)
|
||||
return self.helpers.Refs.CreateGitResetMenu(tag.Name)
|
||||
}
|
||||
|
||||
func (self *TagsController) create() error {
|
||||
// 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 {
|
||||
return func() error {
|
||||
tag := self.context.GetSelected()
|
||||
tag := self.context().GetSelected()
|
||||
if tag == nil {
|
||||
return nil
|
||||
}
|
||||
@ -159,5 +132,9 @@ func (self *TagsController) withSelectedTag(f func(tag *models.Tag) error) func(
|
||||
}
|
||||
|
||||
func (self *TagsController) Context() types.Context {
|
||||
return self.context
|
||||
return self.context()
|
||||
}
|
||||
|
||||
func (self *TagsController) context() *context.TagsContext {
|
||||
return self.contexts.Tags
|
||||
}
|
||||
|
@ -6,8 +6,7 @@ import (
|
||||
|
||||
// all fields mandatory (except `CanRebase` because it's boolean)
|
||||
type SwitchToCommitFilesContextOpts struct {
|
||||
RefName string
|
||||
CanRebase bool
|
||||
Context types.Context
|
||||
WindowName string
|
||||
RefName string
|
||||
CanRebase bool
|
||||
Context types.Context
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package controllers
|
||||
|
||||
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/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
@ -20,34 +18,17 @@ import (
|
||||
|
||||
type UndoController struct {
|
||||
baseController
|
||||
|
||||
c *types.ControllerCommon
|
||||
git *commands.GitCommand
|
||||
|
||||
refsHelper IRefsHelper
|
||||
workingTreeHelper IWorkingTreeHelper
|
||||
|
||||
getFilteredReflogCommits func() []*models.Commit
|
||||
*controllerCommon
|
||||
}
|
||||
|
||||
var _ types.IController = &UndoController{}
|
||||
|
||||
func NewUndoController(
|
||||
c *types.ControllerCommon,
|
||||
git *commands.GitCommand,
|
||||
refsHelper IRefsHelper,
|
||||
workingTreeHelper IWorkingTreeHelper,
|
||||
|
||||
getFilteredReflogCommits func() []*models.Commit,
|
||||
common *controllerCommon,
|
||||
) *UndoController {
|
||||
return &UndoController{
|
||||
baseController: baseController{},
|
||||
c: c,
|
||||
git: git,
|
||||
refsHelper: refsHelper,
|
||||
workingTreeHelper: workingTreeHelper,
|
||||
|
||||
getFilteredReflogCommits: getFilteredReflogCommits,
|
||||
baseController: baseController{},
|
||||
controllerCommon: common,
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,7 +90,7 @@ func (self *UndoController) reflogUndo() error {
|
||||
})
|
||||
case CHECKOUT:
|
||||
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,
|
||||
WaitingStatus: undoingStatus,
|
||||
})
|
||||
@ -147,7 +128,7 @@ func (self *UndoController) reflogRedo() error {
|
||||
})
|
||||
case CHECKOUT:
|
||||
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,
|
||||
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.
|
||||
func (self *UndoController) parseReflogForActions(onUserAction func(counter int, action reflogAction) (bool, error)) error {
|
||||
counter := 0
|
||||
reflogCommits := self.getFilteredReflogCommits()
|
||||
reflogCommits := self.model.FilteredReflogCommits
|
||||
rebaseFinishCommitSha := ""
|
||||
var action *reflogAction
|
||||
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)
|
||||
func (self *UndoController) hardResetWithAutoStash(commitSha string, options hardResetOptions) 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 nil
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// offer to autostash changes
|
||||
return self.c.Ask(types.AskOpts{
|
||||
|
@ -54,7 +54,7 @@ func (gui *Gui) resolveTemplate(templateStr string, promptResponses []string) (s
|
||||
SelectedCommitFile: gui.getSelectedCommitFile(),
|
||||
SelectedCommitFilePath: gui.getSelectedCommitFilePath(),
|
||||
SelectedSubCommit: gui.State.Contexts.SubCommits.GetSelected(),
|
||||
CheckedOutBranch: gui.getCheckedOutBranch(),
|
||||
CheckedOutBranch: gui.helpers.Refs.GetCheckedOutRef(),
|
||||
PromptResponses: promptResponses,
|
||||
}
|
||||
|
||||
|
@ -189,19 +189,6 @@ func (gui *Gui) handleMouseDownMain() error {
|
||||
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) {
|
||||
err = gui.git.Sync.Fetch(git_commands.FetchOptions{Background: true})
|
||||
|
||||
|
149
pkg/gui/gui.go
149
pkg/gui/gui.go
@ -20,6 +20,7 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"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/mergeconflicts"
|
||||
"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
|
||||
|
||||
// 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
|
||||
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
|
||||
// lazygit was opened in, or if we'll retain the one we're currently in.
|
||||
RetainOriginalDir bool
|
||||
@ -161,8 +148,8 @@ type Gui struct {
|
||||
// process
|
||||
InitialDir string
|
||||
|
||||
c *types.ControllerCommon
|
||||
helpers *Helpers
|
||||
c *types.HelperCommon
|
||||
helpers *helpers.Helpers
|
||||
}
|
||||
|
||||
// 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}
|
||||
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
|
||||
// TODO: reset these controllers upon changing repos due to state changing
|
||||
gui.c = controllerCommon
|
||||
gui.c = helperCommon
|
||||
|
||||
authors.SetCustomAuthors(gui.UserConfig.Gui.AuthorColors)
|
||||
presentation.SetCustomBranches(gui.UserConfig.Gui.BranchColors)
|
||||
@ -503,21 +490,23 @@ func NewGui(
|
||||
func (gui *Gui) resetControllers() {
|
||||
controllerCommon := gui.c
|
||||
osCommand := gui.os
|
||||
rebaseHelper := controllers.NewRebaseHelper(controllerCommon, gui.State.Contexts, gui.git, gui.takeOverMergeConflictScrolling)
|
||||
model := gui.State.Model
|
||||
gui.helpers = &Helpers{
|
||||
Refs: controllers.NewRefsHelper(
|
||||
controllerCommon,
|
||||
gui.git,
|
||||
gui.State.Contexts,
|
||||
),
|
||||
Bisect: controllers.NewBisectHelper(controllerCommon, gui.git),
|
||||
Suggestions: controllers.NewSuggestionsHelper(controllerCommon, model, gui.refreshSuggestions),
|
||||
Files: controllers.NewFilesHelper(controllerCommon, gui.git, osCommand),
|
||||
WorkingTree: controllers.NewWorkingTreeHelper(model),
|
||||
Tags: controllers.NewTagsHelper(controllerCommon, gui.git),
|
||||
Rebase: rebaseHelper,
|
||||
CherryPick: controllers.NewCherryPickHelper(
|
||||
refsHelper := helpers.NewRefsHelper(
|
||||
controllerCommon,
|
||||
gui.git,
|
||||
gui.State.Contexts,
|
||||
model,
|
||||
)
|
||||
rebaseHelper := helpers.NewMergeAndRebaseHelper(controllerCommon, gui.State.Contexts, gui.git, gui.takeOverMergeConflictScrolling, refsHelper)
|
||||
gui.helpers = &helpers.Helpers{
|
||||
Refs: refsHelper,
|
||||
Bisect: helpers.NewBisectHelper(controllerCommon, gui.git),
|
||||
Suggestions: helpers.NewSuggestionsHelper(controllerCommon, model, gui.refreshSuggestions),
|
||||
Files: helpers.NewFilesHelper(controllerCommon, gui.git, osCommand),
|
||||
WorkingTree: helpers.NewWorkingTreeHelper(model),
|
||||
Tags: helpers.NewTagsHelper(controllerCommon, gui.git),
|
||||
MergeAndRebase: rebaseHelper,
|
||||
CherryPick: helpers.NewCherryPickHelper(
|
||||
controllerCommon,
|
||||
gui.git,
|
||||
gui.State.Contexts,
|
||||
@ -526,109 +515,58 @@ func (gui *Gui) resetControllers() {
|
||||
),
|
||||
}
|
||||
|
||||
syncController := controllers.NewSyncController(
|
||||
common := controllers.NewControllerCommon(
|
||||
controllerCommon,
|
||||
osCommand,
|
||||
gui.git,
|
||||
gui.getCheckedOutBranch,
|
||||
gui.helpers.Suggestions,
|
||||
gui.helpers,
|
||||
model,
|
||||
gui.State.Contexts,
|
||||
gui.State.Modes,
|
||||
)
|
||||
|
||||
syncController := controllers.NewSyncController(
|
||||
common,
|
||||
gui.getSuggestedRemote,
|
||||
gui.helpers.Rebase.CheckMergeOrRebase,
|
||||
)
|
||||
|
||||
submodulesController := controllers.NewSubmodulesController(
|
||||
controllerCommon,
|
||||
gui.State.Contexts.Submodules,
|
||||
gui.git,
|
||||
common,
|
||||
gui.enterSubmodule,
|
||||
)
|
||||
|
||||
bisectController := controllers.NewBisectController(
|
||||
controllerCommon,
|
||||
gui.State.Contexts.BranchCommits,
|
||||
gui.git,
|
||||
gui.helpers.Bisect,
|
||||
func() []*models.Commit { return gui.State.Model.Commits },
|
||||
)
|
||||
bisectController := controllers.NewBisectController(common)
|
||||
|
||||
gui.Controllers = Controllers{
|
||||
Submodules: submodulesController,
|
||||
Global: controllers.NewGlobalController(
|
||||
controllerCommon,
|
||||
osCommand,
|
||||
),
|
||||
Global: controllers.NewGlobalController(common),
|
||||
Files: controllers.NewFilesController(
|
||||
controllerCommon,
|
||||
gui.State.Contexts.Files,
|
||||
model,
|
||||
gui.git,
|
||||
osCommand,
|
||||
gui.getSelectedFileNode,
|
||||
gui.State.Contexts,
|
||||
common,
|
||||
gui.enterSubmodule,
|
||||
func() []*models.SubmoduleConfig { return gui.State.Model.Submodules },
|
||||
gui.getSetTextareaTextFn(func() *gocui.View { return gui.Views.CommitMessage }),
|
||||
gui.withGpgHandling,
|
||||
func() string { return gui.State.failedCommitMessage },
|
||||
gui.getSelectedPath,
|
||||
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(
|
||||
controllerCommon,
|
||||
gui.State.Contexts.BranchCommits,
|
||||
osCommand,
|
||||
gui.git,
|
||||
gui.helpers.Tags,
|
||||
gui.helpers.Refs,
|
||||
gui.helpers.CherryPick,
|
||||
gui.helpers.Rebase,
|
||||
model,
|
||||
gui.helpers.Rebase.CheckMergeOrRebase,
|
||||
common,
|
||||
syncController.HandlePull,
|
||||
gui.getHostingServiceMgr,
|
||||
gui.SwitchToCommitFilesContext,
|
||||
func() bool { return gui.ShowWholeGitGraph },
|
||||
func(value bool) { gui.ShowWholeGitGraph = value },
|
||||
),
|
||||
Remotes: controllers.NewRemotesController(
|
||||
controllerCommon,
|
||||
gui.State.Contexts.Remotes,
|
||||
gui.git,
|
||||
gui.State.Contexts,
|
||||
common,
|
||||
func(branches []*models.RemoteBranch) { gui.State.Model.RemoteBranches = branches },
|
||||
),
|
||||
Menu: controllers.NewMenuController(
|
||||
controllerCommon,
|
||||
gui.State.Contexts.Menu,
|
||||
),
|
||||
Undo: controllers.NewUndoController(
|
||||
controllerCommon,
|
||||
gui.git,
|
||||
gui.helpers.Refs,
|
||||
gui.helpers.WorkingTree,
|
||||
func() []*models.Commit { return gui.State.Model.FilteredReflogCommits },
|
||||
),
|
||||
Menu: controllers.NewMenuController(common),
|
||||
Undo: controllers.NewUndoController(common),
|
||||
Sync: syncController,
|
||||
}
|
||||
|
||||
branchesController := controllers.NewBranchesController(common)
|
||||
|
||||
switchToSubCommitsControllerFactory := controllers.NewSubCommitsSwitchControllerFactory(
|
||||
controllerCommon,
|
||||
gui.State.Contexts.SubCommits,
|
||||
gui.git,
|
||||
gui.State.Modes,
|
||||
common,
|
||||
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(gui.State.Contexts.Branches, branchesController)
|
||||
controllers.AttachControllers(gui.State.Contexts.Files, gui.Controllers.Files)
|
||||
controllers.AttachControllers(gui.State.Contexts.Tags, gui.Controllers.Tags)
|
||||
controllers.AttachControllers(gui.State.Contexts.Submodules, gui.Controllers.Submodules)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -73,7 +73,7 @@ func (gui *Gui) modeStatuses() []modeStatus {
|
||||
formatWorkingTreeState(workingTreeState), style.FgYellow,
|
||||
)
|
||||
},
|
||||
reset: gui.helpers.Rebase.AbortMergeOrRebaseWithConfirm,
|
||||
reset: gui.helpers.MergeAndRebase.AbortMergeOrRebaseWithConfirm,
|
||||
},
|
||||
{
|
||||
isActive: func() bool {
|
||||
|
@ -102,7 +102,7 @@ func (gui *Gui) handleDeletePatchFromCommit() error {
|
||||
commitIndex := gui.getPatchCommitIndex()
|
||||
gui.c.LogAction(gui.c.Tr.Actions.RemovePatchFromCommit)
|
||||
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()
|
||||
gui.c.LogAction(gui.c.Tr.Actions.MovePatchToSelectedCommit)
|
||||
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()
|
||||
gui.c.LogAction(gui.c.Tr.Actions.MovePatchIntoIndex)
|
||||
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()
|
||||
gui.c.LogAction(gui.c.Tr.Actions.MovePatchIntoNewCommit)
|
||||
err := gui.git.Patch.PullPatchIntoNewCommit(gui.State.Model.Commits, commitIndex)
|
||||
return gui.helpers.Rebase.CheckMergeOrRebase(err)
|
||||
return gui.helpers.MergeAndRebase.CheckMergeOrRebase(err)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
@ -65,10 +65,9 @@ func (gui *Gui) handleViewReflogCommitFiles() error {
|
||||
}
|
||||
|
||||
return gui.SwitchToCommitFilesContext(controllers.SwitchToCommitFilesContextOpts{
|
||||
RefName: commit.Sha,
|
||||
CanRebase: false,
|
||||
Context: gui.State.Contexts.ReflogCommits,
|
||||
WindowName: "commits",
|
||||
RefName: commit.Sha,
|
||||
CanRebase: false,
|
||||
Context: gui.State.Contexts.ReflogCommits,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ func (gui *Gui) refreshCommitsWithLimit() error {
|
||||
FilterPath: gui.State.Modes.Filtering.GetPath(),
|
||||
IncludeRebaseCommits: true,
|
||||
RefName: gui.refForLog(),
|
||||
All: gui.ShowWholeGitGraph,
|
||||
All: gui.State.Contexts.BranchCommits.GetShowWholeGitGraph(),
|
||||
},
|
||||
)
|
||||
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 {
|
||||
gui.OnUIThread(func() error { return gui.helpers.Rebase.PromptToContinueRebase() })
|
||||
gui.OnUIThread(func() error { return gui.helpers.MergeAndRebase.PromptToContinueRebase() })
|
||||
}
|
||||
|
||||
fileTreeViewModel.RWMutex.Lock()
|
||||
@ -526,7 +526,7 @@ func (gui *Gui) refreshStatus() {
|
||||
gui.Mutexes.RefreshingStatusMutex.Lock()
|
||||
defer gui.Mutexes.RefreshingStatusMutex.Unlock()
|
||||
|
||||
currentBranch := gui.getCheckedOutBranch()
|
||||
currentBranch := gui.helpers.Refs.GetCheckedOutRef()
|
||||
if currentBranch == nil {
|
||||
// need to wait for branches to refresh
|
||||
return
|
||||
|
@ -34,7 +34,7 @@ func (gui *Gui) handleRemoteBranchesEscape() error {
|
||||
|
||||
func (gui *Gui) handleMergeRemoteBranch() error {
|
||||
selectedBranchName := gui.State.Contexts.RemoteBranches.GetSelected().FullName()
|
||||
return gui.mergeBranchIntoCheckedOutBranch(selectedBranchName)
|
||||
return gui.helpers.MergeAndRebase.MergeRefIntoCheckedOutBranch(selectedBranchName)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleDeleteRemoteBranch() error {
|
||||
@ -63,12 +63,12 @@ func (gui *Gui) handleDeleteRemoteBranch() error {
|
||||
|
||||
func (gui *Gui) handleRebaseOntoRemoteBranch() error {
|
||||
selectedBranchName := gui.State.Contexts.RemoteBranches.GetSelected().FullName()
|
||||
return gui.handleRebaseOntoBranch(selectedBranchName)
|
||||
return gui.helpers.MergeAndRebase.RebaseOntoRef(selectedBranchName)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleSetBranchUpstream() error {
|
||||
selectedBranch := gui.State.Contexts.RemoteBranches.GetSelected()
|
||||
checkedOutBranch := gui.getCheckedOutBranch()
|
||||
checkedOutBranch := gui.helpers.Refs.GetCheckedOutRef()
|
||||
|
||||
message := utils.ResolvePlaceholderString(
|
||||
gui.c.Tr.SetUpstreamMessage,
|
||||
@ -101,15 +101,6 @@ func (gui *Gui) handleCreateResetToRemoteBranchMenu() error {
|
||||
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 {
|
||||
selectedBranch := gui.State.Contexts.RemoteBranches.GetSelected()
|
||||
if selectedBranch == nil {
|
||||
|
@ -37,8 +37,6 @@ func (gui *Gui) handleStashApply() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
skipStashWarning := gui.c.UserConfig.Gui.SkipStashWarning
|
||||
|
||||
apply := func() error {
|
||||
gui.c.LogAction(gui.c.Tr.Actions.Stash)
|
||||
err := gui.git.Stash.Apply(stashEntry.Index)
|
||||
@ -49,7 +47,7 @@ func (gui *Gui) handleStashApply() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if skipStashWarning {
|
||||
if gui.c.UserConfig.Gui.SkipStashWarning {
|
||||
return apply()
|
||||
}
|
||||
|
||||
@ -68,8 +66,6 @@ func (gui *Gui) handleStashPop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
skipStashWarning := gui.c.UserConfig.Gui.SkipStashWarning
|
||||
|
||||
pop := func() error {
|
||||
gui.c.LogAction(gui.c.Tr.Actions.Stash)
|
||||
err := gui.git.Stash.Pop(stashEntry.Index)
|
||||
@ -80,7 +76,7 @@ func (gui *Gui) handleStashPop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if skipStashWarning {
|
||||
if gui.c.UserConfig.Gui.SkipStashWarning {
|
||||
return pop()
|
||||
}
|
||||
|
||||
@ -125,10 +121,9 @@ func (gui *Gui) handleViewStashFiles() error {
|
||||
}
|
||||
|
||||
return gui.SwitchToCommitFilesContext(controllers.SwitchToCommitFilesContextOpts{
|
||||
RefName: stashEntry.RefName(),
|
||||
CanRebase: false,
|
||||
Context: gui.State.Contexts.Stash,
|
||||
WindowName: "stash",
|
||||
RefName: stashEntry.RefName(),
|
||||
CanRebase: false,
|
||||
Context: gui.State.Contexts.Stash,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ func (gui *Gui) handleCheckForUpdate() error {
|
||||
|
||||
func (gui *Gui) handleStatusClick() error {
|
||||
// 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 {
|
||||
// need to wait for branches to refresh
|
||||
return nil
|
||||
@ -48,7 +48,7 @@ func (gui *Gui) handleStatusClick() error {
|
||||
case enums.REBASE_MODE_REBASING, enums.REBASE_MODE_MERGING:
|
||||
workingTreeStatus := fmt.Sprintf("(%s)", formatWorkingTreeState(workingTreeState))
|
||||
if cursorInSubstring(cx, upstreamStatus+" ", workingTreeStatus) {
|
||||
return gui.helpers.Rebase.CreateRebaseOptionsMenu()
|
||||
return gui.helpers.MergeAndRebase.CreateRebaseOptionsMenu()
|
||||
}
|
||||
if cursorInSubstring(cx, upstreamStatus+" "+workingTreeStatus+" ", repoName) {
|
||||
return gui.handleCreateRecentReposMenu()
|
||||
@ -74,7 +74,6 @@ func formatWorkingTreeState(rebaseMode enums.RebaseMode) string {
|
||||
}
|
||||
|
||||
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(
|
||||
[]string{
|
||||
lazygitTitle(),
|
||||
@ -114,9 +113,8 @@ func (gui *Gui) askForConfigFile(action func(file string) error) error {
|
||||
}
|
||||
}
|
||||
return gui.c.Menu(types.CreateMenuOptions{
|
||||
Title: gui.c.Tr.SelectConfigFile,
|
||||
Items: menuItems,
|
||||
HideCancel: true,
|
||||
Title: gui.c.Tr.SelectConfigFile,
|
||||
Items: menuItems,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -63,10 +63,9 @@ func (gui *Gui) handleViewSubCommitFiles() error {
|
||||
}
|
||||
|
||||
return gui.SwitchToCommitFilesContext(controllers.SwitchToCommitFilesContextOpts{
|
||||
RefName: commit.Sha,
|
||||
CanRebase: false,
|
||||
Context: gui.State.Contexts.SubCommits,
|
||||
WindowName: "branches",
|
||||
RefName: commit.Sha,
|
||||
CanRebase: false,
|
||||
Context: gui.State.Contexts.SubCommits,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"gopkg.in/ozeidan/fuzzy-patricia.v3/patricia"
|
||||
)
|
||||
|
||||
type ControllerCommon struct {
|
||||
type HelperCommon struct {
|
||||
*common.Common
|
||||
IGuiCommon
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user