1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-05-13 22:17:05 +02:00

support viewing a remote branch

This commit is contained in:
Jesse Duffield 2019-11-16 17:35:59 +11:00
parent 61dac10bb9
commit 986abc1e45
11 changed files with 168 additions and 25 deletions

View File

@ -338,18 +338,38 @@ func (gui *Gui) handleFastForward(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) onBranchesTabClick(tabIndex int) error { func (gui *Gui) onBranchesTabClick(tabIndex int) error {
contexts := []string{"local-branches", "remotes", "tabs"} contexts := []string{"local-branches", "remotes", "tabs"}
branchesView := gui.getBranchesView() branchesView := gui.getBranchesView()
branchesView.Context = contexts[tabIndex]
branchesView.TabIndex = tabIndex branchesView.TabIndex = tabIndex
switch contexts[tabIndex] { return gui.switchBranchesPanelContext(contexts[tabIndex])
}
// TODO: make this switch tabs as well if necessary
func (gui *Gui) switchBranchesPanelContext(context string) error {
branchesView := gui.getBranchesView()
branchesView.Context = context
switch context {
case "local-branches": case "local-branches":
if err := gui.renderListPanel(branchesView, gui.State.Branches); err != nil { if err := gui.renderListPanel(branchesView, gui.State.Branches); err != nil {
return err return err
} }
if err := gui.handleBranchSelect(gui.g, gui.getBranchesView()); err != nil {
return err
}
case "remotes": case "remotes":
if err := gui.renderListPanel(branchesView, gui.State.Remotes); err != nil { if err := gui.renderListPanel(branchesView, gui.State.Remotes); err != nil {
return err return err
} }
if err := gui.handleRemoteSelect(gui.g, gui.getBranchesView()); err != nil {
return err
}
case "remote-branches":
if err := gui.renderListPanel(branchesView, gui.State.RemoteBranches); err != nil {
return err
}
if err := gui.handleRemoteBranchSelect(gui.g, gui.getBranchesView()); err != nil {
return err
}
} }
return nil return nil

View File

@ -51,11 +51,7 @@ func (gui *Gui) handleCommitFileSelect(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleSwitchToCommitsPanel(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleSwitchToCommitsPanel(g *gocui.Gui, v *gocui.View) error {
commitsView, err := g.View("commits") return gui.switchFocus(g, v, gui.getCommitsView())
if err != nil {
return err
}
return gui.switchFocus(g, v, commitsView)
} }
func (gui *Gui) handleCheckoutCommitFile(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCheckoutCommitFile(g *gocui.Gui, v *gocui.View) error {

View File

@ -116,6 +116,10 @@ type remotePanelState struct {
SelectedLine int SelectedLine int
} }
type remoteBranchesState struct {
SelectedLine int
}
type commitPanelState struct { type commitPanelState struct {
SelectedLine int SelectedLine int
SpecificDiffMode bool SpecificDiffMode bool
@ -143,6 +147,7 @@ type panelStates struct {
Files *filePanelState Files *filePanelState
Branches *branchPanelState Branches *branchPanelState
Remotes *remotePanelState Remotes *remotePanelState
RemoteBranches *remoteBranchesState
Commits *commitPanelState Commits *commitPanelState
Stash *stashPanelState Stash *stashPanelState
Menu *menuPanelState Menu *menuPanelState
@ -160,6 +165,7 @@ type guiState struct {
CommitFiles []*commands.CommitFile CommitFiles []*commands.CommitFile
DiffEntries []*commands.Commit DiffEntries []*commands.Commit
Remotes []*commands.Remote Remotes []*commands.Remote
RemoteBranches []*commands.Branch // using Branch for now because they're basically the same
MenuItemCount int // can't store the actual list because it's of interface{} type MenuItemCount int // can't store the actual list because it's of interface{} type
PreviousView string PreviousView string
Platform commands.Platform Platform commands.Platform
@ -191,6 +197,7 @@ func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *comma
Files: &filePanelState{SelectedLine: -1}, Files: &filePanelState{SelectedLine: -1},
Branches: &branchPanelState{SelectedLine: 0}, Branches: &branchPanelState{SelectedLine: 0},
Remotes: &remotePanelState{SelectedLine: 0}, Remotes: &remotePanelState{SelectedLine: 0},
RemoteBranches: &remoteBranchesState{SelectedLine: -1},
Commits: &commitPanelState{SelectedLine: -1}, Commits: &commitPanelState{SelectedLine: -1},
CommitFiles: &commitFilesPanelState{SelectedLine: -1}, CommitFiles: &commitFilesPanelState{SelectedLine: -1},
Stash: &stashPanelState{SelectedLine: -1}, Stash: &stashPanelState{SelectedLine: -1},
@ -606,6 +613,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
{view: filesView, context: "", selectedLine: gui.State.Panels.Files.SelectedLine, lineCount: len(gui.State.Files)}, {view: filesView, context: "", selectedLine: gui.State.Panels.Files.SelectedLine, lineCount: len(gui.State.Files)},
{view: branchesView, context: "local-branches", selectedLine: gui.State.Panels.Branches.SelectedLine, lineCount: len(gui.State.Branches)}, {view: branchesView, context: "local-branches", selectedLine: gui.State.Panels.Branches.SelectedLine, lineCount: len(gui.State.Branches)},
{view: branchesView, context: "remotes", selectedLine: gui.State.Panels.Remotes.SelectedLine, lineCount: len(gui.State.Remotes)}, {view: branchesView, context: "remotes", selectedLine: gui.State.Panels.Remotes.SelectedLine, lineCount: len(gui.State.Remotes)},
{view: branchesView, context: "remote-branches", selectedLine: gui.State.Panels.RemoteBranches.SelectedLine, lineCount: len(gui.State.Remotes)},
{view: commitsView, context: "", selectedLine: gui.State.Panels.Commits.SelectedLine, lineCount: len(gui.State.Commits)}, {view: commitsView, context: "", selectedLine: gui.State.Panels.Commits.SelectedLine, lineCount: len(gui.State.Commits)},
{view: stashView, context: "", selectedLine: gui.State.Panels.Stash.SelectedLine, lineCount: len(gui.State.StashEntries)}, {view: stashView, context: "", selectedLine: gui.State.Panels.Stash.SelectedLine, lineCount: len(gui.State.StashEntries)},
} }

View File

@ -414,6 +414,14 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Modifier: gocui.ModNone, Modifier: gocui.ModNone,
Handler: gui.handlePrevBranchesTab, Handler: gui.handlePrevBranchesTab,
}, },
{
ViewName: "branches",
Contexts: []string{"remote-branches"},
Key: gocui.KeyEsc,
Modifier: gocui.ModNone,
Handler: gui.handleRemoteBranchesEscape,
Description: gui.Tr.SLocalize("ReturnToRemotesList"),
},
{ {
ViewName: "commits", ViewName: "commits",
Key: 's', Key: 's',
@ -1026,6 +1034,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Modifier: gocui.ModNone, Modifier: gocui.ModNone,
Handler: gui.handleRemotesClick, Handler: gui.handleRemotesClick,
}, },
{
ViewName: "branches",
Contexts: []string{"remotes"},
Key: gocui.KeyEnter,
Modifier: gocui.ModNone,
Handler: gui.handleRemoteEnter,
},
{ {
ViewName: "commits", ViewName: "commits",
Key: gocui.MouseLeft, Key: gocui.MouseLeft,

View File

@ -75,6 +75,15 @@ func (gui *Gui) getListViews() []*listView {
gui: gui, gui: gui,
rendersToMainView: true, rendersToMainView: true,
}, },
{
viewName: "branches",
context: "remote-branches",
getItemsLength: func() int { return len(gui.State.RemoteBranches) },
getSelectedLine: func() *int { return &gui.State.Panels.RemoteBranches.SelectedLine },
handleItemSelect: gui.handleRemoteBranchSelect,
gui: gui,
rendersToMainView: true,
},
{ {
viewName: "commits", viewName: "commits",
getItemsLength: func() int { return len(gui.State.Commits) }, getItemsLength: func() int { return len(gui.State.Commits) },

View File

@ -0,0 +1,69 @@
package gui
import (
"fmt"
"strings"
"github.com/fatih/color"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/utils"
)
// list panel functions
func (gui *Gui) getSelectedRemoteBranch() *commands.Branch {
selectedLine := gui.State.Panels.RemoteBranches.SelectedLine
if selectedLine == -1 || len(gui.State.RemoteBranches) == 0 {
return nil
}
return gui.State.RemoteBranches[selectedLine]
}
func (gui *Gui) handleRemoteBranchesClick(g *gocui.Gui, v *gocui.View) error {
itemCount := len(gui.State.RemoteBranches)
handleSelect := gui.handleRemoteBranchSelect
selectedLine := &gui.State.Panels.RemoteBranches.SelectedLine
return gui.handleClick(v, itemCount, selectedLine, handleSelect)
}
func (gui *Gui) handleRemoteBranchSelect(g *gocui.Gui, v *gocui.View) error {
if gui.popupPanelFocused() {
return nil
}
gui.State.SplitMainPanel = false
if _, err := gui.g.SetCurrentView(v.Name()); err != nil {
return err
}
gui.getMainView().Title = "Remote Branch"
remote := gui.getSelectedRemote()
remoteBranch := gui.getSelectedRemoteBranch()
if remoteBranch == nil {
return gui.renderString(g, "main", "No branches for this remote")
}
gui.focusPoint(0, gui.State.Panels.Menu.SelectedLine, gui.State.MenuItemCount, v)
if err := gui.focusPoint(0, gui.State.Panels.RemoteBranches.SelectedLine, len(gui.State.RemoteBranches), v); err != nil {
return err
}
go func() {
graph, err := gui.GitCommand.GetBranchGraph(fmt.Sprintf("%s/%s", remote.Name, remoteBranch.Name))
if err != nil && strings.HasPrefix(graph, "fatal: ambiguous argument") {
graph = gui.Tr.SLocalize("NoTrackingThisBranch")
}
_ = gui.renderString(g, "main", fmt.Sprintf("%s/%s\n\n%s", utils.ColoredString(remote.Name, color.FgRed), utils.ColoredString(remoteBranch.Name, color.FgGreen), graph))
}()
return nil
}
func (gui *Gui) handleRemoteBranchesEscape(g *gocui.Gui, v *gocui.View) error {
return gui.switchBranchesPanelContext("remotes")
}

View File

@ -68,3 +68,18 @@ func (gui *Gui) refreshRemotes() error {
return nil return nil
} }
func (gui *Gui) handleRemoteEnter(g *gocui.Gui, v *gocui.View) error {
// naive implementation: get the branches and render them to the list, change the context
remote := gui.getSelectedRemote()
gui.State.RemoteBranches = remote.Branches
newSelectedLine := 0
if len(remote.Branches) == 0 {
newSelectedLine = -1
}
gui.State.Panels.RemoteBranches.SelectedLine = newSelectedLine
return gui.switchBranchesPanelContext("remote-branches")
}

View File

@ -110,6 +110,8 @@ func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error {
return gui.handleBranchSelect(g, v) return gui.handleBranchSelect(g, v)
case "remotes": case "remotes":
return gui.handleRemoteSelect(g, v) return gui.handleRemoteSelect(g, v)
case "remote-branches":
return gui.handleRemoteBranchSelect(g, v)
default: default:
return errors.New("unknown branches panel context: " + branchesView.Context) return errors.New("unknown branches panel context: " + branchesView.Context)
} }

View File

@ -760,6 +760,9 @@ func addDutch(i18nObject *i18n.Bundle) error {
}, &i18n.Message{ }, &i18n.Message{
ID: "EnterUpstream", ID: "EnterUpstream",
Other: `Enter upstream as '<remote> <branchname>'`, Other: `Enter upstream as '<remote> <branchname>'`,
}, &i18n.Message{
ID: "ReturnToRemotesList",
Other: `return to remotes list`,
}, },
) )
} }

View File

@ -846,6 +846,9 @@ func addEnglish(i18nObject *i18n.Bundle) error {
}, &i18n.Message{ }, &i18n.Message{
ID: "notTrackingRemote", ID: "notTrackingRemote",
Other: "(not tracking any remote)", Other: "(not tracking any remote)",
}, &i18n.Message{
ID: "ReturnToRemotesList",
Other: `return to remotes list`,
}, },
) )
} }

View File

@ -743,6 +743,9 @@ func addPolish(i18nObject *i18n.Bundle) error {
}, &i18n.Message{ }, &i18n.Message{
ID: "EnterUpstream", ID: "EnterUpstream",
Other: `Enter upstream as '<remote> <branchname>'`, Other: `Enter upstream as '<remote> <branchname>'`,
}, &i18n.Message{
ID: "ReturnToRemotesList",
Other: `return to remotes list`,
}, },
) )
} }