diff options
author | Luka Markušić <luka.markusic@microblink.com> | 2022-04-08 17:06:07 +0200 |
---|---|---|
committer | Luka Markušić <luka.markusic@microblink.com> | 2022-04-11 14:04:06 +0200 |
commit | f83308c8df529e5a50332ff68a7e7c5106cea414 (patch) | |
tree | acf77d42f80e4be852f8cd386a2abccc0585da29 /pkg/gui/controllers | |
parent | d0e099d2fc306206dac8fee2b8d88d8e178c3ed6 (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.go | 41 | ||||
-rw-r--r-- | pkg/gui/controllers/helpers/helpers.go | 2 | ||||
-rw-r--r-- | pkg/gui/controllers/helpers/upstream_helper.go | 78 | ||||
-rw-r--r-- | pkg/gui/controllers/helpers/upstream_helper_test.go | 31 | ||||
-rw-r--r-- | pkg/gui/controllers/remote_branches_controller.go | 2 | ||||
-rw-r--r-- | pkg/gui/controllers/sync_controller.go | 38 |
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 |