summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2019-11-17 12:02:39 +1100
committerJesse Duffield <jessedduffield@gmail.com>2019-11-21 21:15:49 +1100
commit65f3073e7e362692078fdbc357e04f58acf112d8 (patch)
treed8f35e24c44a1474414cd09c76b9ae9d904c6451
parentff75984796b6d8c7330edcdc703ab264e94c5b63 (diff)
support adding/removing remotes
-rw-r--r--pkg/commands/git.go8
-rw-r--r--pkg/commands/remote.go11
-rw-r--r--pkg/gui/branches_panel.go44
-rw-r--r--pkg/gui/confirmation_panel.go8
-rw-r--r--pkg/gui/keybindings.go16
-rw-r--r--pkg/gui/remote_branches_panel.go14
-rw-r--r--pkg/gui/remotes_panel.go50
-rw-r--r--pkg/i18n/english.go15
8 files changed, 139 insertions, 27 deletions
diff --git a/pkg/commands/git.go b/pkg/commands/git.go
index ad275d10f..26f8aae32 100644
--- a/pkg/commands/git.go
+++ b/pkg/commands/git.go
@@ -1061,3 +1061,11 @@ func (c *GitCommand) BeginInteractiveRebaseForCommit(commits []*Commit, commitIn
func (c *GitCommand) SetUpstreamBranch(upstream string) error {
return c.OSCommand.RunCommand(fmt.Sprintf("git branch -u %s", upstream))
}
+
+func (c *GitCommand) AddRemote(name string, url string) error {
+ return c.OSCommand.RunCommand(fmt.Sprintf("git remote add %s %s", name, url))
+}
+
+func (c *GitCommand) RemoveRemote(name string) error {
+ return c.OSCommand.RunCommand(fmt.Sprintf("git remote remove %s", name))
+}
diff --git a/pkg/commands/remote.go b/pkg/commands/remote.go
index d61f81a53..b3c144b65 100644
--- a/pkg/commands/remote.go
+++ b/pkg/commands/remote.go
@@ -1,5 +1,12 @@
package commands
+import (
+ "fmt"
+
+ "github.com/fatih/color"
+ "github.com/jesseduffield/lazygit/pkg/utils"
+)
+
// Remote : A git remote
type Remote struct {
Name string
@@ -11,5 +18,7 @@ type Remote struct {
// GetDisplayStrings returns the display string of a remote
func (r *Remote) GetDisplayStrings(isFocused bool) []string {
- return []string{r.Name}
+ branchCount := len(r.Branches)
+
+ return []string{r.Name, utils.ColoredString(fmt.Sprintf("%d branches", branchCount), color.FgBlue)}
}
diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go
index 54a9301e2..c47138bd1 100644
--- a/pkg/gui/branches_panel.go
+++ b/pkg/gui/branches_panel.go
@@ -95,9 +95,12 @@ func (gui *Gui) refreshBranches(g *gocui.Gui) error {
}
gui.State.Branches = builder.Build()
- gui.refreshSelectedLine(&gui.State.Panels.Branches.SelectedLine, len(gui.State.Branches))
- if err := gui.RenderSelectedBranchUpstreamDifferences(); err != nil {
- return err
+ // TODO: if we're in the remotes view and we've just deleted a remote we need to refresh accordingly
+ if gui.getBranchesView().Context == "local-branches" {
+ gui.refreshSelectedLine(&gui.State.Panels.Branches.SelectedLine, len(gui.State.Branches))
+ if err := gui.RenderSelectedBranchUpstreamDifferences(); err != nil {
+ return err
+ }
}
return gui.refreshStatus(g)
@@ -105,6 +108,20 @@ func (gui *Gui) refreshBranches(g *gocui.Gui) error {
return nil
}
+func (gui *Gui) renderLocalBranchesWithSelection() error {
+ branchesView := gui.getBranchesView()
+
+ gui.refreshSelectedLine(&gui.State.Panels.Branches.SelectedLine, len(gui.State.Branches))
+ if err := gui.renderListPanel(branchesView, gui.State.Branches); err != nil {
+ return err
+ }
+ if err := gui.handleBranchSelect(gui.g, branchesView); err != nil {
+ return err
+ }
+
+ return nil
+}
+
// specific functions
func (gui *Gui) handleBranchPress(g *gocui.Gui, v *gocui.View) error {
@@ -350,26 +367,11 @@ func (gui *Gui) switchBranchesPanelContext(context string) error {
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
- }
+ return gui.renderLocalBranchesWithSelection()
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
- }
+ return gui.renderRemotesWithSelection()
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 gui.renderRemoteBranchesWithSelection()
}
return nil
diff --git a/pkg/gui/confirmation_panel.go b/pkg/gui/confirmation_panel.go
index db0bf7bdc..0638f6fba 100644
--- a/pkg/gui/confirmation_panel.go
+++ b/pkg/gui/confirmation_panel.go
@@ -17,12 +17,18 @@ import (
func (gui *Gui) wrappedConfirmationFunction(function func(*gocui.Gui, *gocui.View) error, returnFocusOnClose bool) func(*gocui.Gui, *gocui.View) error {
return func(g *gocui.Gui, v *gocui.View) error {
+
+ if err := gui.closeConfirmationPrompt(g, returnFocusOnClose); err != nil {
+ return err
+ }
+
if function != nil {
if err := function(g, v); err != nil {
return err
}
}
- return gui.closeConfirmationPrompt(g, returnFocusOnClose)
+
+ return nil
}
}
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index a67894999..eb817e76d 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -1042,6 +1042,22 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
Handler: gui.handleRemoteEnter,
},
{
+ ViewName: "branches",
+ Contexts: []string{"remotes"},
+ Key: 'n',
+ Modifier: gocui.ModNone,
+ Handler: gui.handleAddRemote,
+ Description: gui.Tr.SLocalize("addNewRemote"),
+ },
+ {
+ ViewName: "branches",
+ Contexts: []string{"remotes"},
+ Key: 'd',
+ Modifier: gocui.ModNone,
+ Handler: gui.handleRemoveRemote,
+ Description: gui.Tr.SLocalize("removeRemote"),
+ },
+ {
ViewName: "commits",
Key: gocui.MouseLeft,
Modifier: gocui.ModNone,
diff --git a/pkg/gui/remote_branches_panel.go b/pkg/gui/remote_branches_panel.go
index 544e8bf81..f47ea9f63 100644
--- a/pkg/gui/remote_branches_panel.go
+++ b/pkg/gui/remote_branches_panel.go
@@ -67,3 +67,17 @@ func (gui *Gui) handleRemoteBranchSelect(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) handleRemoteBranchesEscape(g *gocui.Gui, v *gocui.View) error {
return gui.switchBranchesPanelContext("remotes")
}
+
+func (gui *Gui) renderRemoteBranchesWithSelection() error {
+ branchesView := gui.getBranchesView()
+
+ gui.refreshSelectedLine(&gui.State.Panels.RemoteBranches.SelectedLine, len(gui.State.RemoteBranches))
+ if err := gui.renderListPanel(branchesView, gui.State.RemoteBranches); err != nil {
+ return err
+ }
+ if err := gui.handleRemoteBranchSelect(gui.g, branchesView); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/pkg/gui/remotes_panel.go b/pkg/gui/remotes_panel.go
index c63b2f07d..1402cfd0f 100644
--- a/pkg/gui/remotes_panel.go
+++ b/pkg/gui/remotes_panel.go
@@ -60,10 +60,23 @@ func (gui *Gui) refreshRemotes() error {
gui.State.Remotes = remotes
- gui.g.Update(func(g *gocui.Gui) error {
- gui.refreshSelectedLine(&gui.State.Panels.Remotes.SelectedLine, len(gui.State.Remotes))
- return nil
- })
+ if gui.getBranchesView().Context == "remotes" {
+ return gui.renderRemotesWithSelection()
+ }
+
+ return nil
+}
+
+func (gui *Gui) renderRemotesWithSelection() error {
+ branchesView := gui.getBranchesView()
+
+ gui.refreshSelectedLine(&gui.State.Panels.Remotes.SelectedLine, len(gui.State.Remotes))
+ if err := gui.renderListPanel(branchesView, gui.State.Remotes); err != nil {
+ return err
+ }
+ if err := gui.handleRemoteSelect(gui.g, branchesView); err != nil {
+ return err
+ }
return nil
}
@@ -82,3 +95,32 @@ func (gui *Gui) handleRemoteEnter(g *gocui.Gui, v *gocui.View) error {
return gui.switchBranchesPanelContext("remote-branches")
}
+
+func (gui *Gui) handleAddRemote(g *gocui.Gui, v *gocui.View) error {
+ branchesView := gui.getBranchesView()
+ return gui.createPromptPanel(g, branchesView, gui.Tr.SLocalize("newRemoteName"), "", func(g *gocui.Gui, v *gocui.View) error {
+ remoteName := gui.trimmedContent(v)
+ return gui.createPromptPanel(g, branchesView, gui.Tr.SLocalize("newRemoteUrl"), "", func(g *gocui.Gui, v *gocui.View) error {
+ remoteUrl := gui.trimmedContent(v)
+ if err := gui.GitCommand.AddRemote(remoteName, remoteUrl); err != nil {
+ return err
+ }
+ return gui.refreshRemotes()
+ })
+ })
+}
+
+func (gui *Gui) handleRemoveRemote(g *gocui.Gui, v *gocui.View) error {
+ remote := gui.getSelectedRemote()
+ if remote == nil {
+ return nil
+ }
+ return gui.createConfirmationPanel(g, v, true, gui.Tr.SLocalize("removeRemote"), gui.Tr.SLocalize("removeRemotePrompt")+" '"+remote.Name+"'?", func(*gocui.Gui, *gocui.View) error {
+ if err := gui.GitCommand.RemoveRemote(remote.Name); err != nil {
+ return err
+ }
+
+ return gui.refreshRemotes()
+
+ }, nil)
+}
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index 62c762fdd..135c52bda 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -849,6 +849,21 @@ func addEnglish(i18nObject *i18n.Bundle) error {
}, &i18n.Message{
ID: "ReturnToRemotesList",
Other: `return to remotes list`,
+ }, &i18n.Message{
+ ID: "addNewRemote",
+ Other: `add new remote`,
+ }, &i18n.Message{
+ ID: "newRemoteName",
+ Other: `New remote name:`,
+ }, &i18n.Message{
+ ID: "newRemoteUrl",
+ Other: `New remote url:`,
+ }, &i18n.Message{
+ ID: "removeRemote",
+ Other: `remove remote`,
+ }, &i18n.Message{
+ ID: "removeRemotePrompt",
+ Other: "Are you sure you want to remove remote",
},
)
}