mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-07-18 10:02:15 +03:00
At the same time, we change the defaults for both of them to "date" (they were "recency" and "alphabetical", respectively, before). This is the reason we need to touch so many integration tests. For some of them I decided to adapt the test assertions to the changed sort order; for others, I added a SetupConfig step to set the order back to "recency" so that I don't have to change what the test does (e.g. how many SelectNextItem() calls are needed to get to a certain branch).
201 lines
6.9 KiB
Go
201 lines
6.9 KiB
Go
package controllers
|
|
|
|
import (
|
|
"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
|
|
*ListControllerTrait[*models.RemoteBranch]
|
|
c *ControllerCommon
|
|
}
|
|
|
|
var _ types.IController = &RemoteBranchesController{}
|
|
|
|
func NewRemoteBranchesController(
|
|
c *ControllerCommon,
|
|
) *RemoteBranchesController {
|
|
return &RemoteBranchesController{
|
|
baseController: baseController{},
|
|
ListControllerTrait: NewListControllerTrait(
|
|
c,
|
|
c.Contexts().RemoteBranches,
|
|
c.Contexts().RemoteBranches.GetSelected,
|
|
c.Contexts().RemoteBranches.GetSelectedItems,
|
|
),
|
|
c: c,
|
|
}
|
|
}
|
|
|
|
func (self *RemoteBranchesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
|
return []*types.Binding{
|
|
{
|
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
|
Handler: self.withItem(self.checkoutBranch),
|
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
|
Description: self.c.Tr.Checkout,
|
|
Tooltip: self.c.Tr.RemoteBranchCheckoutTooltip,
|
|
DisplayOnScreen: true,
|
|
},
|
|
{
|
|
Key: opts.GetKey(opts.Config.Universal.New),
|
|
Handler: self.withItem(self.newLocalBranch),
|
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
|
Description: self.c.Tr.NewBranch,
|
|
},
|
|
{
|
|
Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch),
|
|
Handler: opts.Guards.OutsideFilterMode(self.withItem(self.merge)),
|
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
|
Description: self.c.Tr.Merge,
|
|
Tooltip: self.c.Tr.MergeBranchTooltip,
|
|
DisplayOnScreen: true,
|
|
},
|
|
{
|
|
Key: opts.GetKey(opts.Config.Branches.RebaseBranch),
|
|
Handler: opts.Guards.OutsideFilterMode(self.withItem(self.rebase)),
|
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
|
Description: self.c.Tr.RebaseBranch,
|
|
Tooltip: self.c.Tr.RebaseBranchTooltip,
|
|
DisplayOnScreen: true,
|
|
},
|
|
{
|
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
|
Handler: self.withItems(self.delete),
|
|
GetDisabledReason: self.require(self.itemRangeSelected()),
|
|
Description: self.c.Tr.Delete,
|
|
Tooltip: self.c.Tr.DeleteRemoteBranchTooltip,
|
|
DisplayOnScreen: true,
|
|
},
|
|
{
|
|
Key: opts.GetKey(opts.Config.Branches.SetUpstream),
|
|
Handler: self.withItem(self.setAsUpstream),
|
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
|
Description: self.c.Tr.SetAsUpstream,
|
|
Tooltip: self.c.Tr.SetAsUpstreamTooltip,
|
|
DisplayOnScreen: true,
|
|
},
|
|
{
|
|
Key: opts.GetKey(opts.Config.Branches.SortOrder),
|
|
Handler: self.createSortMenu,
|
|
Description: self.c.Tr.SortOrder,
|
|
OpensMenu: true,
|
|
},
|
|
{
|
|
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
|
Handler: self.withItem(self.createResetMenu),
|
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
|
Description: self.c.Tr.ViewResetOptions,
|
|
Tooltip: self.c.Tr.ResetTooltip,
|
|
OpensMenu: true,
|
|
},
|
|
{
|
|
Key: opts.GetKey(opts.Config.Universal.OpenDiffTool),
|
|
Handler: self.withItem(func(selectedBranch *models.RemoteBranch) error {
|
|
return self.c.Helpers().Diff.OpenDiffToolForRef(selectedBranch)
|
|
}),
|
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
|
Description: self.c.Tr.OpenDiffTool,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (self *RemoteBranchesController) GetOnRenderToMain() func() {
|
|
return func() {
|
|
self.c.Helpers().Diff.WithDiffModeCheck(func() {
|
|
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())
|
|
}
|
|
|
|
self.c.RenderToMainViews(types.RefreshMainOpts{
|
|
Pair: self.c.MainViewPairs().Normal,
|
|
Main: &types.ViewUpdateOpts{
|
|
Title: "Remote Branch",
|
|
Task: task,
|
|
},
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
func (self *RemoteBranchesController) context() *context.RemoteBranchesContext {
|
|
return self.c.Contexts().RemoteBranches
|
|
}
|
|
|
|
func (self *RemoteBranchesController) delete(selectedBranches []*models.RemoteBranch) error {
|
|
return self.c.Helpers().BranchesHelper.ConfirmDeleteRemote(selectedBranches, true)
|
|
}
|
|
|
|
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) createSortMenu() error {
|
|
return self.c.Helpers().Refs.CreateSortOrderMenu([]string{"alphabetical", "date"}, func(sortOrder string) error {
|
|
if self.c.UserConfig().Git.RemoteBranchSortOrder != sortOrder {
|
|
self.c.UserConfig().Git.RemoteBranchSortOrder = sortOrder
|
|
self.c.Contexts().RemoteBranches.SetSelection(0)
|
|
self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.REMOTES}})
|
|
}
|
|
return nil
|
|
},
|
|
self.c.UserConfig().Git.RemoteBranchSortOrder)
|
|
}
|
|
|
|
func (self *RemoteBranchesController) createResetMenu(selectedBranch *models.RemoteBranch) error {
|
|
return self.c.Helpers().Refs.CreateGitResetMenu(selectedBranch.FullName(), selectedBranch.FullRefName())
|
|
}
|
|
|
|
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(),
|
|
},
|
|
)
|
|
|
|
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 err
|
|
}
|
|
|
|
self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.BRANCHES, types.REMOTES}})
|
|
return nil
|
|
},
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
func (self *RemoteBranchesController) checkoutBranch(selectedBranch *models.RemoteBranch) error {
|
|
return self.c.Helpers().Refs.CheckoutRemoteBranch(selectedBranch.FullName(), selectedBranch.Name)
|
|
}
|