1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-04-02 22:25:47 +02:00
lazygit/pkg/gui/controllers/remote_branches_controller.go
Jesse Duffield cd989d8ebe Fix escape logic for remote branches
The remote branches controller was using its own escape method meaning it didn't go through the flow of cancelling
an active filter. It's now using the same approach as the sub-commits and commit-files contexts: defining a parent
context to return to upon hittin escape.
2023-07-03 12:54:14 +10:00

176 lines
5.6 KiB
Go

package controllers
import (
"fmt"
"strings"
"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 RemoteBranchesController struct {
baseController
c *ControllerCommon
}
var _ types.IController = &RemoteBranchesController{}
func NewRemoteBranchesController(
common *ControllerCommon,
) *RemoteBranchesController {
return &RemoteBranchesController{
baseController: baseController{},
c: common,
}
}
func (self *RemoteBranchesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
return []*types.Binding{
{
Key: opts.GetKey(opts.Config.Universal.Select),
// gonna use the exact same handler as the 'n' keybinding because everybody wants this to happen when they checkout a remote branch
Handler: self.checkSelected(self.newLocalBranch),
Description: self.c.Tr.Checkout,
},
{
Key: opts.GetKey(opts.Config.Universal.New),
Handler: self.checkSelected(self.newLocalBranch),
Description: self.c.Tr.NewBranch,
},
{
Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch),
Handler: opts.Guards.OutsideFilterMode(self.checkSelected(self.merge)),
Description: self.c.Tr.MergeIntoCurrentBranch,
},
{
Key: opts.GetKey(opts.Config.Branches.RebaseBranch),
Handler: opts.Guards.OutsideFilterMode(self.checkSelected(self.rebase)),
Description: self.c.Tr.RebaseBranch,
},
{
Key: opts.GetKey(opts.Config.Universal.Remove),
Handler: self.checkSelected(self.delete),
Description: self.c.Tr.DeleteBranch,
},
{
Key: opts.GetKey(opts.Config.Branches.SetUpstream),
Handler: self.checkSelected(self.setAsUpstream),
Description: self.c.Tr.SetAsUpstream,
},
{
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
Handler: self.checkSelected(self.createResetMenu),
Description: self.c.Tr.ViewResetOptions,
OpensMenu: true,
},
}
}
func (self *RemoteBranchesController) GetOnRenderToMain() func() error {
return func() error {
return self.c.Helpers().Diff.WithDiffModeCheck(func() error {
var task types.UpdateTask
remoteBranch := self.context().GetSelected()
if remoteBranch == nil {
task = types.NewRenderStringTask("No branches for this remote")
} else {
cmdObj := self.c.Git().Branch.GetGraphCmdObj(remoteBranch.FullRefName())
task = types.NewRunCommandTask(cmdObj.GetCmd())
}
return self.c.RenderToMainViews(types.RefreshMainOpts{
Pair: self.c.MainViewPairs().Normal,
Main: &types.ViewUpdateOpts{
Title: "Remote Branch",
Task: task,
},
})
})
}
}
func (self *RemoteBranchesController) Context() types.Context {
return self.context()
}
func (self *RemoteBranchesController) context() *context.RemoteBranchesContext {
return self.c.Contexts().RemoteBranches
}
func (self *RemoteBranchesController) checkSelected(callback func(*models.RemoteBranch) error) func() error {
return func() error {
selectedItem := self.context().GetSelected()
if selectedItem == nil {
return nil
}
return callback(selectedItem)
}
}
func (self *RemoteBranchesController) delete(selectedBranch *models.RemoteBranch) error {
message := fmt.Sprintf("%s '%s'?", self.c.Tr.DeleteRemoteBranchMessage, selectedBranch.FullName())
return self.c.Confirm(types.ConfirmOpts{
Title: self.c.Tr.DeleteRemoteBranch,
Prompt: message,
HandleConfirm: func() error {
return self.c.WithWaitingStatus(self.c.Tr.DeletingStatus, func() error {
self.c.LogAction(self.c.Tr.Actions.DeleteRemoteBranch)
err := self.c.Git().Remote.DeleteRemoteBranch(selectedBranch.RemoteName, selectedBranch.Name)
if err != nil {
_ = self.c.Error(err)
}
return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.BRANCHES, types.REMOTES}})
})
},
})
}
func (self *RemoteBranchesController) merge(selectedBranch *models.RemoteBranch) error {
return self.c.Helpers().MergeAndRebase.MergeRefIntoCheckedOutBranch(selectedBranch.FullName())
}
func (self *RemoteBranchesController) rebase(selectedBranch *models.RemoteBranch) error {
return self.c.Helpers().MergeAndRebase.RebaseOntoRef(selectedBranch.FullName())
}
func (self *RemoteBranchesController) createResetMenu(selectedBranch *models.RemoteBranch) error {
return self.c.Helpers().Refs.CreateGitResetMenu(selectedBranch.FullName())
}
func (self *RemoteBranchesController) setAsUpstream(selectedBranch *models.RemoteBranch) error {
checkedOutBranch := self.c.Helpers().Refs.GetCheckedOutRef()
message := utils.ResolvePlaceholderString(
self.c.Tr.SetUpstreamMessage,
map[string]string{
"checkedOut": checkedOutBranch.Name,
"selected": selectedBranch.FullName(),
},
)
return self.c.Confirm(types.ConfirmOpts{
Title: self.c.Tr.SetUpstreamTitle,
Prompt: message,
HandleConfirm: func() error {
self.c.LogAction(self.c.Tr.Actions.SetBranchUpstream)
if err := self.c.Git().Branch.SetUpstream(selectedBranch.RemoteName, selectedBranch.Name, checkedOutBranch.Name); err != nil {
return self.c.Error(err)
}
return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.BRANCHES, types.REMOTES}})
},
})
}
func (self *RemoteBranchesController) newLocalBranch(selectedBranch *models.RemoteBranch) error {
// will set to the remote's branch name without the remote name
nameSuggestion := strings.SplitAfterN(selectedBranch.RefName(), "/", 2)[1]
return self.c.Helpers().Refs.NewBranch(selectedBranch.RefName(), selectedBranch.RefName(), nameSuggestion)
}