diff options
author | Mark Kopenga <mkopenga@gmail.com> | 2018-12-08 16:41:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-08 16:41:39 +0100 |
commit | 19a6a32625d59c61ecfe91ef8626390eb34a922a (patch) | |
tree | b02d1a9c8477d2614f99cc80b40b54accf28c127 /pkg/gui/branches_panel.go | |
parent | 270658fc009dc254a80501fc1c9f5f82acd27239 (diff) | |
parent | ff856b763033a241370bfde98d7386b43b7d0893 (diff) |
Merge branch 'master' into https-ask-for-username-password
Diffstat (limited to 'pkg/gui/branches_panel.go')
-rw-r--r-- | pkg/gui/branches_panel.go | 187 |
1 files changed, 129 insertions, 58 deletions
diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index 059f0af50..e54d6e8c1 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -7,25 +7,116 @@ import ( "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/git" - "github.com/jesseduffield/lazygit/pkg/utils" ) +// list panel functions + +func (gui *Gui) getSelectedBranch() *commands.Branch { + selectedLine := gui.State.Panels.Branches.SelectedLine + if selectedLine == -1 { + return nil + } + + return gui.State.Branches[selectedLine] +} + +// may want to standardise how these select methods work +func (gui *Gui) handleBranchSelect(g *gocui.Gui, v *gocui.View) error { + // This really shouldn't happen: there should always be a master branch + if len(gui.State.Branches) == 0 { + return gui.renderString(g, "main", gui.Tr.SLocalize("NoBranchesThisRepo")) + } + branch := gui.getSelectedBranch() + if err := gui.focusPoint(0, gui.State.Panels.Branches.SelectedLine, v); err != nil { + return err + } + go func() { + _ = gui.RenderSelectedBranchUpstreamDifferences() + }() + go func() { + graph, err := gui.GitCommand.GetBranchGraph(branch.Name) + if err != nil && strings.HasPrefix(graph, "fatal: ambiguous argument") { + graph = gui.Tr.SLocalize("NoTrackingThisBranch") + } + _ = gui.renderString(g, "main", graph) + }() + return nil +} + +func (gui *Gui) RenderSelectedBranchUpstreamDifferences() error { + // here we tell the selected branch that it is selected. + // this is necessary for showing stats on a branch that is selected, because + // the displaystring function doesn't have access to gui state to tell if it's selected + for i, branch := range gui.State.Branches { + branch.Selected = i == gui.State.Panels.Branches.SelectedLine + } + + branch := gui.getSelectedBranch() + branch.Pushables, branch.Pullables = gui.GitCommand.GetBranchUpstreamDifferenceCount(branch.Name) + return gui.renderListPanel(gui.getBranchesView(gui.g), gui.State.Branches) +} + +// gui.refreshStatus is called at the end of this because that's when we can +// be sure there is a state.Branches array to pick the current branch from +func (gui *Gui) refreshBranches(g *gocui.Gui) error { + g.Update(func(g *gocui.Gui) error { + builder, err := git.NewBranchListBuilder(gui.Log, gui.GitCommand) + if err != nil { + return err + } + gui.State.Branches = builder.Build() + + gui.refreshSelectedLine(&gui.State.Panels.Branches.SelectedLine, len(gui.State.Branches)) + if err := gui.resetOrigin(gui.getBranchesView(gui.g)); err != nil { + return err + } + if err := gui.RenderSelectedBranchUpstreamDifferences(); err != nil { + return err + } + + return gui.refreshStatus(g) + }) + return nil +} + +func (gui *Gui) handleBranchesNextLine(g *gocui.Gui, v *gocui.View) error { + panelState := gui.State.Panels.Branches + gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Branches), false) + return gui.handleBranchSelect(gui.g, v) +} + +func (gui *Gui) handleBranchesPrevLine(g *gocui.Gui, v *gocui.View) error { + panelState := gui.State.Panels.Branches + gui.changeSelectedLine(&panelState.SelectedLine, len(gui.State.Branches), true) + + return gui.handleBranchSelect(gui.g, v) +} + +// specific functions + func (gui *Gui) handleBranchPress(g *gocui.Gui, v *gocui.View) error { - index := gui.getItemPosition(gui.getBranchesView(g)) - if index == 0 { + if gui.State.Panels.Branches.SelectedLine == -1 { + return nil + } + if gui.State.Panels.Branches.SelectedLine == 0 { return gui.createErrorPanel(g, gui.Tr.SLocalize("AlreadyCheckedOutBranch")) } - branch := gui.getSelectedBranch(gui.getBranchesView(g)) + branch := gui.getSelectedBranch() if err := gui.GitCommand.Checkout(branch.Name, false); err != nil { - gui.createErrorPanel(g, err.Error()) + if err := gui.createErrorPanel(g, err.Error()); err != nil { + return err + } + } else { + gui.State.Panels.Branches.SelectedLine = 0 } + return gui.refreshSidePanels(g) } func (gui *Gui) handleCreatePullRequestPress(g *gocui.Gui, v *gocui.View) error { - branch := gui.getSelectedBranch(gui.getBranchesView(g)) pullRequest := commands.NewPullRequest(gui.GitCommand) + branch := gui.getSelectedBranch() if err := pullRequest.Create(branch); err != nil { return gui.createErrorPanel(g, err.Error()) } @@ -60,7 +151,7 @@ func (gui *Gui) handleGitFetch(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleForceCheckout(g *gocui.Gui, v *gocui.View) error { - branch := gui.getSelectedBranch(v) + branch := gui.getSelectedBranch() message := gui.Tr.SLocalize("SureForceCheckout") title := gui.Tr.SLocalize("ForceCheckoutBranch") return gui.createConfirmationPanel(g, v, title, message, func(g *gocui.Gui, v *gocui.View) error { @@ -108,8 +199,11 @@ func (gui *Gui) handleForceDeleteBranch(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) deleteBranch(g *gocui.Gui, v *gocui.View, force bool) error { + selectedBranch := gui.getSelectedBranch() + if selectedBranch == nil { + return nil + } checkedOutBranch := gui.State.Branches[0] - selectedBranch := gui.getSelectedBranch(v) if checkedOutBranch.Name == selectedBranch.Name { return gui.createErrorPanel(g, gui.Tr.SLocalize("CantDeleteCheckOutBranch")) } @@ -144,7 +238,7 @@ func (gui *Gui) deleteNamedBranch(g *gocui.Gui, v *gocui.View, selectedBranch *c func (gui *Gui) handleMerge(g *gocui.Gui, v *gocui.View) error { checkedOutBranch := gui.State.Branches[0] - selectedBranch := gui.getSelectedBranch(v) + selectedBranch := gui.getSelectedBranch() defer gui.refreshSidePanels(g) if checkedOutBranch.Name == selectedBranch.Name { return gui.createErrorPanel(g, gui.Tr.SLocalize("CantMergeBranchIntoItself")) @@ -155,59 +249,36 @@ func (gui *Gui) handleMerge(g *gocui.Gui, v *gocui.View) error { return nil } -func (gui *Gui) getSelectedBranch(v *gocui.View) *commands.Branch { - lineNumber := gui.getItemPosition(v) - return gui.State.Branches[lineNumber] -} - -func (gui *Gui) renderBranchesOptions(g *gocui.Gui) error { - return gui.renderGlobalOptions(g) -} - -// may want to standardise how these select methods work -func (gui *Gui) handleBranchSelect(g *gocui.Gui, v *gocui.View) error { - if err := gui.renderBranchesOptions(g); err != nil { - return err +func (gui *Gui) handleFastForward(g *gocui.Gui, v *gocui.View) error { + branch := gui.getSelectedBranch() + if branch == nil { + return nil } - // This really shouldn't happen: there should always be a master branch - if len(gui.State.Branches) == 0 { - return gui.renderString(g, "main", gui.Tr.SLocalize("NoBranchesThisRepo")) + if branch.Pushables == "" { + return nil + } + if branch.Pushables == "?" { + return gui.createErrorPanel(gui.g, "Cannot fast-forward a branch with no upstream") + } + if branch.Pushables != "0" { + return gui.createErrorPanel(gui.g, "Cannot fast-forward a branch with commits to push") } + upstream := "origin" // hardcoding for now + message := gui.Tr.TemplateLocalize( + "Fetching", + Teml{ + "from": fmt.Sprintf("%s/%s", upstream, branch.Name), + "to": branch.Name, + }, + ) go func() { - branch := gui.getSelectedBranch(v) - diff, err := gui.GitCommand.GetBranchGraph(branch.Name) - if err != nil && strings.HasPrefix(diff, "fatal: ambiguous argument") { - diff = gui.Tr.SLocalize("NoTrackingThisBranch") + _ = gui.createMessagePanel(gui.g, v, "", message) + if err := gui.GitCommand.FastForward(branch.Name); err != nil { + _ = gui.createErrorPanel(gui.g, err.Error()) + } else { + _ = gui.closeConfirmationPrompt(gui.g) + _ = gui.RenderSelectedBranchUpstreamDifferences() } - gui.renderString(g, "main", diff) }() return nil } - -// gui.refreshStatus is called at the end of this because that's when we can -// be sure there is a state.Branches array to pick the current branch from -func (gui *Gui) refreshBranches(g *gocui.Gui) error { - g.Update(func(g *gocui.Gui) error { - v, err := g.View("branches") - if err != nil { - panic(err) - } - builder, err := git.NewBranchListBuilder(gui.Log, gui.GitCommand) - if err != nil { - return err - } - gui.State.Branches = builder.Build() - - v.Clear() - list, err := utils.RenderList(gui.State.Branches) - if err != nil { - return err - } - - fmt.Fprint(v, list) - - gui.resetOrigin(v) - return gui.refreshStatus(g) - }) - return nil -} |