summaryrefslogtreecommitdiffstats
path: root/pkg/gui/controllers
diff options
context:
space:
mode:
authorLuka Markušić <luka.markusic@microblink.com>2022-04-08 17:06:07 +0200
committerLuka Markušić <luka.markusic@microblink.com>2022-04-11 14:04:06 +0200
commitf83308c8df529e5a50332ff68a7e7c5106cea414 (patch)
treeacf77d42f80e4be852f8cd386a2abccc0585da29 /pkg/gui/controllers
parentd0e099d2fc306206dac8fee2b8d88d8e178c3ed6 (diff)
Add option to (un)set upstream for a local branch
Diffstat (limited to 'pkg/gui/controllers')
-rw-r--r--pkg/gui/controllers/branches_controller.go41
-rw-r--r--pkg/gui/controllers/helpers/helpers.go2
-rw-r--r--pkg/gui/controllers/helpers/upstream_helper.go78
-rw-r--r--pkg/gui/controllers/helpers/upstream_helper_test.go31
-rw-r--r--pkg/gui/controllers/remote_branches_controller.go2
-rw-r--r--pkg/gui/controllers/sync_controller.go38
6 files changed, 157 insertions, 35 deletions
diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go
index 2caa30525..4bf439f1c 100644
--- a/pkg/gui/controllers/branches_controller.go
+++ b/pkg/gui/controllers/branches_controller.go
@@ -97,9 +97,50 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty
Handler: self.checkSelectedAndReal(self.rename),
Description: self.c.Tr.LcRenameBranch,
},
+ {
+ Key: opts.GetKey(opts.Config.Branches.SetUpstream),
+ Handler: self.checkSelected(self.setUpstream),
+ Description: self.c.Tr.LcSetUnsetUpstream,
+ OpensMenu: true,
+ },
}
}
+func (self *BranchesController) setUpstream(selectedBranch *models.Branch) error {
+ return self.c.Menu(types.CreateMenuOptions{
+ Title: self.c.Tr.Actions.SetUnsetUpstream,
+ Items: []*types.MenuItem{
+ {
+ DisplayStrings: []string{self.c.Tr.LcUnsetUpstream},
+ OnPress: func() error {
+ if err := self.git.Branch.UnsetUpstream(selectedBranch.Name); err != nil {
+ return self.c.Error(err)
+ }
+ return nil
+ },
+ Key: 'u',
+ },
+ {
+ DisplayStrings: []string{self.c.Tr.LcSetUpstream},
+ OnPress: func() error {
+ return self.helpers.Upstream.PromptForUpstream(selectedBranch, func(upstream string) error {
+ upstreamRemote, upstreamBranch, err := self.helpers.Upstream.ParseUpstream(upstream)
+ if err != nil {
+ return self.c.Error(err)
+ }
+
+ if err := self.git.Branch.SetUpstream(upstreamRemote, upstreamBranch, selectedBranch.Name); err != nil {
+ return self.c.Error(err)
+ }
+ return nil
+ })
+ },
+ Key: 's',
+ },
+ },
+ })
+}
+
func (self *BranchesController) Context() types.Context {
return self.context()
}
diff --git a/pkg/gui/controllers/helpers/helpers.go b/pkg/gui/controllers/helpers/helpers.go
index c45852e29..61fdedf46 100644
--- a/pkg/gui/controllers/helpers/helpers.go
+++ b/pkg/gui/controllers/helpers/helpers.go
@@ -12,6 +12,7 @@ type Helpers struct {
Host *HostHelper
PatchBuilding *PatchBuildingHelper
GPG *GpgHelper
+ Upstream *UpstreamHelper
}
func NewStubHelpers() *Helpers {
@@ -27,5 +28,6 @@ func NewStubHelpers() *Helpers {
Host: &HostHelper{},
PatchBuilding: &PatchBuildingHelper{},
GPG: &GpgHelper{},
+ Upstream: &UpstreamHelper{},
}
}
diff --git a/pkg/gui/controllers/helpers/upstream_helper.go b/pkg/gui/controllers/helpers/upstream_helper.go
new file mode 100644
index 000000000..a0307a9d4
--- /dev/null
+++ b/pkg/gui/controllers/helpers/upstream_helper.go
@@ -0,0 +1,78 @@
+package helpers
+
+import (
+ "errors"
+ "strings"
+
+ "github.com/jesseduffield/lazygit/pkg/commands/models"
+ "github.com/jesseduffield/lazygit/pkg/gui/types"
+)
+
+type UpstreamHelper struct {
+ c *types.HelperCommon
+ model *types.Model
+
+ getRemoteBranchesSuggestionsFunc func(string) func(string) []*types.Suggestion
+}
+
+type IUpstreamHelper interface {
+ ParseUpstream(string) (string, string, error)
+ PromptForUpstream(*models.Branch, func(string) error) error
+ GetSuggestedRemote() string
+}
+
+var _ IUpstreamHelper = &UpstreamHelper{}
+
+func NewUpstreamHelper(
+ c *types.HelperCommon,
+ model *types.Model,
+ getRemoteBranchesSuggestionsFunc func(string) func(string) []*types.Suggestion,
+) *UpstreamHelper {
+ return &UpstreamHelper{
+ c: c,
+ model: model,
+ getRemoteBranchesSuggestionsFunc: getRemoteBranchesSuggestionsFunc,
+ }
+}
+
+func (self *UpstreamHelper) ParseUpstream(upstream string) (string, string, error) {
+ var upstreamBranch, upstreamRemote string
+ split := strings.Split(upstream, " ")
+ if len(split) != 2 {
+ return "", "", errors.New(self.c.Tr.InvalidUpstream)
+ }
+
+ upstreamRemote = split[0]
+ upstreamBranch = split[1]
+
+ return upstreamRemote, upstreamBranch, nil
+}
+
+func (self *UpstreamHelper) PromptForUpstream(currentBranch *models.Branch, onConfirm func(string) error) error {
+ suggestedRemote := self.GetSuggestedRemote()
+
+ return self.c.Prompt(types.PromptOpts{
+ Title: self.c.Tr.EnterUpstream,
+ InitialContent: suggestedRemote + " " + currentBranch.Name,
+ FindSuggestionsFunc: self.getRemoteBranchesSuggestionsFunc(" "),
+ HandleConfirm: onConfirm,
+ })
+}
+
+func (self *UpstreamHelper) GetSuggestedRemote() string {
+ return getSuggestedRemote(self.model.Remotes)
+}
+
+func getSuggestedRemote(remotes []*models.Remote) string {
+ if len(remotes) == 0 {
+ return "origin"
+ }
+
+ for _, remote := range remotes {
+ if remote.Name == "origin" {
+ return remote.Name
+ }
+ }
+
+ return remotes[0].Name
+}
diff --git a/pkg/gui/controllers/helpers/upstream_helper_test.go b/pkg/gui/controllers/helpers/upstream_helper_test.go
new file mode 100644
index 000000000..ac7a6a8bf
--- /dev/null
+++ b/pkg/gui/controllers/helpers/upstream_helper_test.go
@@ -0,0 +1,31 @@
+package helpers
+
+import (
+ "testing"
+
+ "github.com/jesseduffield/generics/slices"
+ "github.com/jesseduffield/lazygit/pkg/commands/models"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestGetSuggestedRemote(t *testing.T) {
+ cases := []struct {
+ remotes []*models.Remote
+ expected string
+ }{
+ {mkRemoteList(), "origin"},
+ {mkRemoteList("upstream", "origin", "foo"), "origin"},
+ {mkRemoteList("upstream", "foo", "bar"), "upstream"},
+ }
+
+ for _, c := range cases {
+ result := getSuggestedRemote(c.remotes)
+ assert.EqualValues(t, c.expected, result)
+ }
+}
+
+func mkRemoteList(names ...string) []*models.Remote {
+ return slices.Map(names, func(name string) *models.Remote {
+ return &models.Remote{Name: name}
+ })
+}
diff --git a/pkg/gui/controllers/remote_branches_controller.go b/pkg/gui/controllers/remote_branches_controller.go
index b75cf3b13..dcedde8c0 100644
--- a/pkg/gui/controllers/remote_branches_controller.go
+++ b/pkg/gui/controllers/remote_branches_controller.go
@@ -57,7 +57,7 @@ func (self *RemoteBranchesController) GetKeybindings(opts types.KeybindingsOpts)
{
Key: opts.GetKey(opts.Config.Branches.SetUpstream),
Handler: self.checkSelected(self.setAsUpstream),
- Description: self.c.Tr.LcSetUpstream,
+ Description: self.c.Tr.LcSetAsUpstream,
},
{
Key: opts.GetKey(opts.Config.Universal.Return),
diff --git a/pkg/gui/controllers/sync_controller.go b/pkg/gui/controllers/sync_controller.go
index 69663f32e..046edb369 100644
--- a/pkg/gui/controllers/sync_controller.go
+++ b/pkg/gui/controllers/sync_controller.go
@@ -1,7 +1,6 @@
package controllers
import (
- "errors"
"fmt"
"strings"
@@ -13,21 +12,16 @@ import (
type SyncController struct {
baseController
*controllerCommon
-
- getSuggestedRemote func() string
}
var _ types.IController = &SyncController{}
func NewSyncController(
common *controllerCommon,
- getSuggestedRemote func() string,
) *SyncController {
return &SyncController{
baseController: baseController{},
controllerCommon: common,
-
- getSuggestedRemote: getSuggestedRemote,
}
}
@@ -85,8 +79,8 @@ func (self *SyncController) push(currentBranch *models.Branch) error {
if self.git.Config.GetPushToCurrent() {
return self.pushAux(pushOpts{setUpstream: true})
} else {
- return self.promptForUpstream(currentBranch, func(upstream string) error {
- upstreamRemote, upstreamBranch, err := self.parseUpstream(upstream)
+ return self.helpers.Upstream.PromptForUpstream(currentBranch, func(upstream string) error {
+ upstreamRemote, upstreamBranch, err := self.helpers.Upstream.ParseUpstream(upstream)
if err != nil {
return self.c.Error(err)
}
@@ -106,7 +100,7 @@ func (self *SyncController) pull(currentBranch *models.Branch) error {
// if we have no upstream branch we need to set that first
if !currentBranch.IsTrackingRemote() {
- return self.promptForUpstream(currentBranch, func(upstream string) error {
+ return self.helpers.Upstream.PromptForUpstream(currentBranch, func(upstream string) error {
if err := self.setCurrentBranchUpstream(upstream); err != nil {
return self.c.Error(err)
}
@@ -119,7 +113,7 @@ func (self *SyncController) pull(currentBranch *models.Branch) error {
}
func (self *SyncController) setCurrentBranchUpstream(upstream string) error {
- upstreamRemote, upstreamBranch, err := self.parseUpstream(upstream)
+ upstreamRemote, upstreamBranch, err := self.helpers.Upstream.ParseUpstream(upstream)
if err != nil {
return err
}
@@ -136,30 +130,6 @@ func (self *SyncController) setCurrentBranchUpstream(upstream string) error {
return nil
}
-func (self *SyncController) parseUpstream(upstream string) (string, string, error) {
- var upstreamBranch, upstreamRemote string
- split := strings.Split(upstream, " ")
- if len(split) != 2 {
- return "", "", errors.New(self.c.Tr.InvalidUpstream)
- }
-
- upstreamRemote = split[0]
- upstreamBranch = split[1]
-
- return upstreamRemote, upstreamBranch, nil
-}
-
-func (self *SyncController) promptForUpstream(currentBranch *models.Branch, onConfirm func(string) error) error {
- suggestedRemote := self.getSuggestedRemote()
-
- return self.c.Prompt(types.PromptOpts{
- Title: self.c.Tr.EnterUpstream,
- InitialContent: suggestedRemote + " " + currentBranch.Name,
- FindSuggestionsFunc: self.helpers.Suggestions.GetRemoteBranchesSuggestionsFunc(" "),
- HandleConfirm: onConfirm,
- })
-}
-
type PullFilesOptions struct {
UpstreamRemote string
UpstreamBranch string