summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2019-11-16 17:35:59 +1100
committerJesse Duffield <jessedduffield@gmail.com>2019-11-21 22:07:14 +1100
commit986abc1e45e314e68beb7c0ba92804e60c99310b (patch)
tree788b7f689a051c414bec231489279f0f41a949bd
parent61dac10bb94874800d7b955c875cbcc3b3efa546 (diff)
support viewing a remote branch
-rw-r--r--pkg/gui/branches_panel.go24
-rw-r--r--pkg/gui/commit_files_panel.go6
-rw-r--r--pkg/gui/gui.go44
-rw-r--r--pkg/gui/keybindings.go15
-rw-r--r--pkg/gui/list_view.go9
-rw-r--r--pkg/gui/remote_branches_panel.go69
-rw-r--r--pkg/gui/remotes_panel.go15
-rw-r--r--pkg/gui/view_helpers.go2
-rw-r--r--pkg/i18n/dutch.go3
-rw-r--r--pkg/i18n/english.go3
-rw-r--r--pkg/i18n/polish.go3
11 files changed, 168 insertions, 25 deletions
diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go
index cd1a9a69b..54a9301e2 100644
--- a/pkg/gui/branches_panel.go
+++ b/pkg/gui/branches_panel.go
@@ -338,18 +338,38 @@ func (gui *Gui) handleFastForward(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) onBranchesTabClick(tabIndex int) error {
contexts := []string{"local-branches", "remotes", "tabs"}
branchesView := gui.getBranchesView()
- branchesView.Context = contexts[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":
if err := gui.renderListPanel(branchesView, gui.State.Branches); err != nil {
return err
}
+ if err := gui.handleBranchSelect(gui.g, gui.getBranchesView()); err != nil {
+ return err
+ }
case "remotes":
if err := gui.renderListPanel(branchesView, gui.State.Remotes); err != nil {
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
diff --git a/pkg/gui/commit_files_panel.go b/pkg/gui/commit_files_panel.go
index efd3c5fae..1dee4a3cd 100644
--- a/pkg/gui/commit_files_panel.go
+++ b/pkg/gui/commit_files_panel.go
@@ -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 {
- commitsView, err := g.View("commits")
- if err != nil {
- return err
- }
- return gui.switchFocus(g, v, commitsView)
+ return gui.switchFocus(g, v, gui.getCommitsView())
}
func (gui *Gui) handleCheckoutCommitFile(g *gocui.Gui, v *gocui.View) error {
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index e8056f858..f4a343626 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -116,6 +116,10 @@ type remotePanelState struct {
SelectedLine int
}
+type remoteBranchesState struct {
+ SelectedLine int
+}
+
type commitPanelState struct {
SelectedLine int
SpecificDiffMode bool
@@ -140,16 +144,17 @@ type statusPanelState struct {
}
type panelStates struct {
- Files *filePanelState
- Branches *branchPanelState
- Remotes *remotePanelState
- Commits *commitPanelState
- Stash *stashPanelState
- Menu *menuPanelState
- LineByLine *lineByLinePanelState
- Merging *mergingPanelState
- CommitFiles *commitFilesPanelState
- Status *statusPanelState
+ Files *filePanelState
+ Branches *branchPanelState
+ Remotes *remotePanelState
+ RemoteBranches *remoteBranchesState
+ Commits *commitPanelState
+ Stash *stashPanelState
+ Menu *menuPanelState
+ LineByLine *lineByLinePanelState
+ Merging *mergingPanelState
+ CommitFiles *commitFilesPanelState
+ Status *statusPanelState
}
type guiState struct {
@@ -160,7 +165,8 @@ type guiState struct {
CommitFiles []*commands.CommitFile
DiffEntries []*commands.Commit
Remotes []*commands.Remote
- MenuItemCount int // can't store the actual list because it's of interface{} type
+ 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
PreviousView string
Platform commands.Platform
Updating bool
@@ -188,13 +194,14 @@ func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *comma
DiffEntries: make([]*commands.Commit, 0),
Platform: *oSCommand.Platform,
Panels: &panelStates{
- Files: &filePanelState{SelectedLine: -1},
- Branches: &branchPanelState{SelectedLine: 0},
- Remotes: &remotePanelState{SelectedLine: 0},
- Commits: &commitPanelState{SelectedLine: -1},
- CommitFiles: &commitFilesPanelState{SelectedLine: -1},
- Stash: &stashPanelState{SelectedLine: -1},
- Menu: &menuPanelState{SelectedLine: 0},
+ Files: &filePanelState{SelectedLine: -1},
+ Branches: &branchPanelState{SelectedLine: 0},
+ Remotes: &remotePanelState{SelectedLine: 0},
+ RemoteBranches: &remoteBranchesState{SelectedLine: -1},
+ Commits: &commitPanelState{SelectedLine: -1},
+ CommitFiles: &commitFilesPanelState{SelectedLine: -1},
+ Stash: &stashPanelState{SelectedLine: -1},
+ Menu: &menuPanelState{SelectedLine: 0},
Merging: &mergingPanelState{
ConflictIndex: 0,
ConflictTop: true,
@@ -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: 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: "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: stashView, context: "", selectedLine: gui.State.Panels.Stash.SelectedLine, lineCount: len(gui.State.StashEntries)},
}
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index 3b469d81e..a67894999 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -415,6 +415,14 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
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",
Key: 's',
Modifier: gocui.ModNone,
@@ -1027,6 +1035,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Handler: gui.handleRemotesClick,
},
{
+ ViewName: "branches",
+ Contexts: []string{"remotes"},
+ Key: gocui.KeyEnter,
+ Modifier: gocui.ModNone,
+ Handler: gui.handleRemoteEnter,
+ },
+ {
ViewName: "commits",
Key: gocui.MouseLeft,
Modifier: gocui.ModNone,
diff --git a/pkg/gui/list_view.go b/pkg/gui/list_view.go
index 98dd9414e..bdfa33f1c 100644
--- a/pkg/gui/list_view.go
+++ b/pkg/gui/list_view.go
@@ -76,6 +76,15 @@ func (gui *Gui) getListViews() []*listView {
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",
getItemsLength: func() int { return len(gui.State.Commits) },
getSelectedLine: func() *int { return &gui.State.Panels.Commits.SelectedLine },
diff --git a/pkg/gui/remote_branches_panel.go b/pkg/gui/remote_branches_panel.go
new file mode 100644
index 000000000..93978bc3c
--- /dev/null
+++ b/pkg/gui/remote_branches_panel.go
@@ -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")
+}
diff --git a/pkg/gui/remotes_panel.go b/pkg/gui/remotes_panel.go
index d40515716..38ec8b44b 100644
--- a/pkg/gui/remotes_panel.go
+++ b/pkg/gui/remotes_panel.go
@@ -68,3 +68,18 @@ func (gui *Gui) refreshRemotes() error {
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")
+}
diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go
index 076567386..8c72252cb 100644
--- a/pkg/gui/view_helpers.go
+++ b/pkg/gui/view_helpers.go
@@ -110,6 +110,8 @@ func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error {
return gui.handleBranchSelect(g, v)
case "remotes":
return gui.handleRemoteSelect(g, v)
+ case "remote-branches":
+ return gui.handleRemoteBranchSelect(g, v)
default:
return errors.New("unknown branches panel context: " + branchesView.Context)
}
diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go
index f11ce7342..ca76f0a5a 100644
--- a/pkg/i18n/dutch.go
+++ b/pkg/i18n/dutch.go
@@ -760,6 +760,9 @@ func addDutch(i18nObject *i18n.Bundle) error {
}, &i18n.Message{
ID: "EnterUpstream",
Other: `Enter upstream as '<remote> <branchname>'`,
+ }, &i18n.Message{
+ ID: "ReturnToRemotesList",
+ Other: `return to remotes list`,
},
)
}
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index ee53cc1b9..62c762fdd 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -846,6 +846,9 @@ func addEnglish(i18nObject *i18n.Bundle) error {
}, &i18n.Message{
ID: "notTrackingRemote",
Other: "(not tracking any remote)",
+ }, &i18n.Message{
+ ID: "ReturnToRemotesList",
+ Other: `return to remotes list`,
},
)
}
diff --git a/pkg/i18n/polish.go b/pkg/i18n/polish.go
index 3bd6e93f0..bd9d4bc10 100644
--- a/pkg/i18n/polish.go
+++ b/pkg/i18n/polish.go
@@ -743,6 +743,9 @@ func addPolish(i18nObject *i18n.Bundle) error {
}, &i18n.Message{
ID: "EnterUpstream",
Other: `Enter upstream as '<remote> <branchname>'`,
+ }, &i18n.Message{
+ ID: "ReturnToRemotesList",
+ Other: `return to remotes list`,
},
)
}