mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-02-03 13:21:56 +02:00
Add option to (un)set upstream for a local branch
This commit is contained in:
parent
d0e099d2fc
commit
f83308c8df
@ -59,6 +59,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
<kbd>f</kbd>: fast-forward this branch from its upstream
|
||||
<kbd>g</kbd>: view reset options
|
||||
<kbd>R</kbd>: rename branch
|
||||
<kbd>u</kbd>: set/unset upstream
|
||||
<kbd>enter</kbd>: view commits
|
||||
</pre>
|
||||
|
||||
|
@ -86,6 +86,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
<kbd>f</kbd>: fast-forward deze branch vanaf zijn upstream
|
||||
<kbd>g</kbd>: bekijk reset opties
|
||||
<kbd>R</kbd>: hernoem branch
|
||||
<kbd>u</kbd>: set/unset upstream
|
||||
<kbd>enter</kbd>: bekijk commits
|
||||
</pre>
|
||||
|
||||
|
@ -59,6 +59,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
<kbd>f</kbd>: fast-forward this branch from its upstream
|
||||
<kbd>g</kbd>: wyświetl opcje resetu
|
||||
<kbd>R</kbd>: rename branch
|
||||
<kbd>u</kbd>: set/unset upstream
|
||||
<kbd>enter</kbd>: view commits
|
||||
</pre>
|
||||
|
||||
|
@ -74,6 +74,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
|
||||
<kbd>f</kbd>: 从上游快进此分支
|
||||
<kbd>g</kbd>: 查看重置选项
|
||||
<kbd>R</kbd>: 重命名分支
|
||||
<kbd>u</kbd>: set/unset upstream
|
||||
<kbd>enter</kbd>: 查看提交
|
||||
</pre>
|
||||
|
||||
|
@ -109,6 +109,10 @@ func (self *BranchCommands) SetUpstream(remoteName string, remoteBranchName stri
|
||||
return self.cmd.New(fmt.Sprintf("git branch --set-upstream-to=%s/%s %s", self.cmd.Quote(remoteName), self.cmd.Quote(remoteBranchName), self.cmd.Quote(branchName))).Run()
|
||||
}
|
||||
|
||||
func (self *BranchCommands) UnsetUpstream(branchName string) error {
|
||||
return self.cmd.New(fmt.Sprintf("git branch --unset-upstream %s", self.cmd.Quote(branchName))).Run()
|
||||
}
|
||||
|
||||
func (self *BranchCommands) GetCurrentBranchUpstreamDifferenceCount() (string, string) {
|
||||
return self.GetCommitDifferences("HEAD", "HEAD@{u}")
|
||||
}
|
||||
|
@ -23,12 +23,13 @@ func (gui *Gui) resetControllers() {
|
||||
)
|
||||
|
||||
rebaseHelper := helpers.NewMergeAndRebaseHelper(helperCommon, gui.State.Contexts, gui.git, gui.takeOverMergeConflictScrolling, refsHelper)
|
||||
suggestionsHelper := helpers.NewSuggestionsHelper(helperCommon, model, gui.refreshSuggestions)
|
||||
gui.helpers = &helpers.Helpers{
|
||||
Refs: refsHelper,
|
||||
Host: helpers.NewHostHelper(helperCommon, gui.git),
|
||||
PatchBuilding: helpers.NewPatchBuildingHelper(helperCommon, gui.git),
|
||||
Bisect: helpers.NewBisectHelper(helperCommon, gui.git),
|
||||
Suggestions: helpers.NewSuggestionsHelper(helperCommon, model, gui.refreshSuggestions),
|
||||
Suggestions: suggestionsHelper,
|
||||
Files: helpers.NewFilesHelper(helperCommon, gui.git, osCommand),
|
||||
WorkingTree: helpers.NewWorkingTreeHelper(helperCommon, gui.git, model),
|
||||
Tags: helpers.NewTagsHelper(helperCommon, gui.git),
|
||||
@ -41,6 +42,7 @@ func (gui *Gui) resetControllers() {
|
||||
func() *cherrypicking.CherryPicking { return gui.State.Modes.CherryPicking },
|
||||
rebaseHelper,
|
||||
),
|
||||
Upstream: helpers.NewUpstreamHelper(helperCommon, model, suggestionsHelper.GetRemoteBranchesSuggestionsFunc),
|
||||
}
|
||||
|
||||
gui.CustomCommandsClient = custom_commands.NewClient(
|
||||
@ -64,7 +66,6 @@ func (gui *Gui) resetControllers() {
|
||||
|
||||
syncController := controllers.NewSyncController(
|
||||
common,
|
||||
gui.getSuggestedRemote,
|
||||
)
|
||||
|
||||
submodulesController := controllers.NewSubmodulesController(
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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{},
|
||||
}
|
||||
}
|
||||
|
78
pkg/gui/controllers/helpers/upstream_helper.go
Normal file
78
pkg/gui/controllers/helpers/upstream_helper.go
Normal file
@ -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
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package gui
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"testing"
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -1,25 +0,0 @@
|
||||
package gui
|
||||
|
||||
import "github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
|
||||
// this file is to put things where it's not obvious where they belong while this refactor takes place
|
||||
|
||||
func (gui *Gui) getSuggestedRemote() string {
|
||||
remotes := gui.State.Model.Remotes
|
||||
|
||||
return getSuggestedRemote(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
|
||||
}
|
@ -312,6 +312,7 @@ func chineseTranslationSet() TranslationSet {
|
||||
DeleteRemoteBranch: "删除远程分支",
|
||||
DeleteRemoteBranchMessage: "您确定要删除远程分支吗?",
|
||||
LcSetUpstream: "设置为检出分支的上游",
|
||||
LcSetAsUpstream: "设置为检出分支的上游",
|
||||
SetUpstreamTitle: "设置上游分支",
|
||||
SetUpstreamMessage: "您确定要将 {{.checkedOut}} 的上游分支设置为 {{.selected}} 吗?",
|
||||
LcEditRemote: "编辑远程仓库",
|
||||
|
@ -271,6 +271,7 @@ func dutchTranslationSet() TranslationSet {
|
||||
DeleteRemoteBranch: "Verwijder Remote Branch",
|
||||
DeleteRemoteBranchMessage: "Weet je zeker dat je deze remote branch wilt verwijderen",
|
||||
LcSetUpstream: "stel in als upstream van uitgecheckte branch",
|
||||
LcSetAsUpstream: "stel in als upstream van uitgecheckte branch",
|
||||
SetUpstreamTitle: "Stel in als upstream branch",
|
||||
SetUpstreamMessage: "Weet je zeker dat je de upstream branch van '{{.checkedOut}}' naar '{{.selected}}' wilt zetten",
|
||||
LcEditRemote: "wijzig remote",
|
||||
|
@ -306,7 +306,9 @@ type TranslationSet struct {
|
||||
LcRemoveRemotePrompt string
|
||||
DeleteRemoteBranch string
|
||||
DeleteRemoteBranchMessage string
|
||||
LcSetAsUpstream string
|
||||
LcSetUpstream string
|
||||
LcUnsetUpstream string
|
||||
SetUpstreamTitle string
|
||||
SetUpstreamMessage string
|
||||
LcEditRemote string
|
||||
@ -339,6 +341,7 @@ type TranslationSet struct {
|
||||
Panel string
|
||||
Keybindings string
|
||||
LcRenameBranch string
|
||||
LcSetUnsetUpstream string
|
||||
NewGitFlowBranchPrompt string
|
||||
RenameBranchWarning string
|
||||
LcOpenMenu string
|
||||
@ -506,6 +509,7 @@ type Actions struct {
|
||||
Merge string
|
||||
RebaseBranch string
|
||||
RenameBranch string
|
||||
SetUnsetUpstream string
|
||||
CreateBranch string
|
||||
FastForwardBranch string
|
||||
CherryPick string
|
||||
@ -906,7 +910,9 @@ func EnglishTranslationSet() TranslationSet {
|
||||
LcRemoveRemotePrompt: "Are you sure you want to remove remote",
|
||||
DeleteRemoteBranch: "Delete Remote Branch",
|
||||
DeleteRemoteBranchMessage: "Are you sure you want to delete remote branch",
|
||||
LcSetUpstream: "set as upstream of checked-out branch",
|
||||
LcSetAsUpstream: "set as upstream of checked-out branch",
|
||||
LcSetUpstream: "set upstream of selected branch",
|
||||
LcUnsetUpstream: "unset upstream of selected branch",
|
||||
SetUpstreamTitle: "Set upstream branch",
|
||||
SetUpstreamMessage: "Are you sure you want to set the upstream branch of '{{.checkedOut}}' to '{{.selected}}'",
|
||||
LcEditRemote: "edit remote",
|
||||
@ -939,6 +945,7 @@ func EnglishTranslationSet() TranslationSet {
|
||||
Panel: "Panel",
|
||||
Keybindings: "Keybindings",
|
||||
LcRenameBranch: "rename branch",
|
||||
LcSetUnsetUpstream: "set/unset upstream",
|
||||
NewBranchNamePrompt: "Enter new branch name for branch",
|
||||
RenameBranchWarning: "This branch is tracking a remote. This action will only rename the local branch name, not the name of the remote branch. Continue?",
|
||||
LcOpenMenu: "open menu",
|
||||
@ -1088,6 +1095,7 @@ func EnglishTranslationSet() TranslationSet {
|
||||
Merge: "Merge",
|
||||
RebaseBranch: "Rebase branch",
|
||||
RenameBranch: "Rename branch",
|
||||
SetUnsetUpstream: "Set/unset upstream",
|
||||
CreateBranch: "Create branch",
|
||||
CherryPick: "(Cherry-pick) Paste commits",
|
||||
CheckoutFile: "Checkout file",
|
||||
|
Loading…
x
Reference in New Issue
Block a user