mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-06-23 00:39:13 +02:00
Support creating worktrees from refs
This commit is contained in:
@ -6,8 +6,6 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type WorktreeCommands struct {
|
type WorktreeCommands struct {
|
||||||
@ -20,10 +18,30 @@ func NewWorktreeCommands(gitCommon *GitCommon) *WorktreeCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *WorktreeCommands) New(worktreePath string, committish string) error {
|
type NewWorktreeOpts struct {
|
||||||
cmdArgs := NewGitCmd("worktree").Arg("add", worktreePath, committish).ToArgv()
|
// required. The path of the new worktree.
|
||||||
|
Path string
|
||||||
|
// required. The base branch/ref.
|
||||||
|
Base string
|
||||||
|
|
||||||
return self.cmd.New(cmdArgs).Run()
|
// if true, ends up with a detached head
|
||||||
|
Detach bool
|
||||||
|
|
||||||
|
// optional. if empty, and if detach is false, we will checkout the base
|
||||||
|
Branch string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *WorktreeCommands) New(opts NewWorktreeOpts) error {
|
||||||
|
if opts.Detach && opts.Branch != "" {
|
||||||
|
panic("cannot specify branch when detaching")
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdArgs := NewGitCmd("worktree").Arg("add").
|
||||||
|
ArgIf(opts.Detach, "--detach").
|
||||||
|
ArgIf(opts.Branch != "", "-b", opts.Branch).
|
||||||
|
Arg(opts.Path, opts.Base)
|
||||||
|
|
||||||
|
return self.cmd.New(cmdArgs.ToArgv()).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *WorktreeCommands) Delete(worktreePath string, force bool) error {
|
func (self *WorktreeCommands) Delete(worktreePath string, force bool) error {
|
||||||
@ -38,25 +56,25 @@ func (self *WorktreeCommands) Detach(worktreePath string) error {
|
|||||||
return self.cmd.New(cmdArgs).SetWd(worktreePath).Run()
|
return self.cmd.New(cmdArgs).SetWd(worktreePath).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *WorktreeCommands) IsCurrentWorktree(w *models.Worktree) bool {
|
func (self *WorktreeCommands) IsCurrentWorktree(path string) bool {
|
||||||
return IsCurrentWorktree(w)
|
return IsCurrentWorktree(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsCurrentWorktree(w *models.Worktree) bool {
|
func IsCurrentWorktree(path string) bool {
|
||||||
pwd, err := os.Getwd()
|
pwd, err := os.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err.Error())
|
log.Fatalln(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return EqualPath(pwd, w.Path)
|
return EqualPath(pwd, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *WorktreeCommands) IsWorktreePathMissing(w *models.Worktree) bool {
|
func (self *WorktreeCommands) IsWorktreePathMissing(path string) bool {
|
||||||
if _, err := os.Stat(w.Path); err != nil {
|
if _, err := os.Stat(path); err != nil {
|
||||||
if errors.Is(err, fs.ErrNotExist) {
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
log.Fatalln(fmt.Errorf("failed to check if worktree path `%s` exists\n%w", w.Path, err).Error())
|
log.Fatalln(fmt.Errorf("failed to check if worktree path `%s` exists\n%w", path, err).Error())
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -132,6 +132,7 @@ type KeybindingConfig struct {
|
|||||||
Status KeybindingStatusConfig `yaml:"status"`
|
Status KeybindingStatusConfig `yaml:"status"`
|
||||||
Files KeybindingFilesConfig `yaml:"files"`
|
Files KeybindingFilesConfig `yaml:"files"`
|
||||||
Branches KeybindingBranchesConfig `yaml:"branches"`
|
Branches KeybindingBranchesConfig `yaml:"branches"`
|
||||||
|
Worktrees KeybindingWorktreesConfig `yaml:"worktrees"`
|
||||||
Commits KeybindingCommitsConfig `yaml:"commits"`
|
Commits KeybindingCommitsConfig `yaml:"commits"`
|
||||||
Stash KeybindingStashConfig `yaml:"stash"`
|
Stash KeybindingStashConfig `yaml:"stash"`
|
||||||
CommitFiles KeybindingCommitFilesConfig `yaml:"commitFiles"`
|
CommitFiles KeybindingCommitFilesConfig `yaml:"commitFiles"`
|
||||||
@ -246,6 +247,10 @@ type KeybindingBranchesConfig struct {
|
|||||||
FetchRemote string `yaml:"fetchRemote"`
|
FetchRemote string `yaml:"fetchRemote"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type KeybindingWorktreesConfig struct {
|
||||||
|
ViewWorktreeOptions string `yaml:"viewWorktreeOptions"`
|
||||||
|
}
|
||||||
|
|
||||||
type KeybindingCommitsConfig struct {
|
type KeybindingCommitsConfig struct {
|
||||||
SquashDown string `yaml:"squashDown"`
|
SquashDown string `yaml:"squashDown"`
|
||||||
RenameCommit string `yaml:"renameCommit"`
|
RenameCommit string `yaml:"renameCommit"`
|
||||||
@ -587,6 +592,9 @@ func GetDefaultConfig() *UserConfig {
|
|||||||
SetUpstream: "u",
|
SetUpstream: "u",
|
||||||
FetchRemote: "f",
|
FetchRemote: "f",
|
||||||
},
|
},
|
||||||
|
Worktrees: KeybindingWorktreesConfig{
|
||||||
|
ViewWorktreeOptions: "w",
|
||||||
|
},
|
||||||
Commits: KeybindingCommitsConfig{
|
Commits: KeybindingCommitsConfig{
|
||||||
SquashDown: "s",
|
SquashDown: "s",
|
||||||
RenameCommit: "r",
|
RenameCommit: "r",
|
||||||
|
@ -18,6 +18,9 @@ func (gui *Gui) Helpers() *helpers.Helpers {
|
|||||||
|
|
||||||
func (gui *Gui) resetHelpersAndControllers() {
|
func (gui *Gui) resetHelpersAndControllers() {
|
||||||
helperCommon := gui.c
|
helperCommon := gui.c
|
||||||
|
recordDirectoryHelper := helpers.NewRecordDirectoryHelper(helperCommon)
|
||||||
|
reposHelper := helpers.NewRecentReposHelper(helperCommon, recordDirectoryHelper, gui.onNewRepo)
|
||||||
|
worktreeHelper := helpers.NewWorktreeHelper(helperCommon, reposHelper)
|
||||||
refsHelper := helpers.NewRefsHelper(helperCommon)
|
refsHelper := helpers.NewRefsHelper(helperCommon)
|
||||||
|
|
||||||
rebaseHelper := helpers.NewMergeAndRebaseHelper(helperCommon, refsHelper)
|
rebaseHelper := helpers.NewMergeAndRebaseHelper(helperCommon, refsHelper)
|
||||||
@ -41,12 +44,10 @@ func (gui *Gui) resetHelpersAndControllers() {
|
|||||||
|
|
||||||
gpgHelper := helpers.NewGpgHelper(helperCommon)
|
gpgHelper := helpers.NewGpgHelper(helperCommon)
|
||||||
viewHelper := helpers.NewViewHelper(helperCommon, gui.State.Contexts)
|
viewHelper := helpers.NewViewHelper(helperCommon, gui.State.Contexts)
|
||||||
recordDirectoryHelper := helpers.NewRecordDirectoryHelper(helperCommon)
|
|
||||||
patchBuildingHelper := helpers.NewPatchBuildingHelper(helperCommon)
|
patchBuildingHelper := helpers.NewPatchBuildingHelper(helperCommon)
|
||||||
stagingHelper := helpers.NewStagingHelper(helperCommon)
|
stagingHelper := helpers.NewStagingHelper(helperCommon)
|
||||||
mergeConflictsHelper := helpers.NewMergeConflictsHelper(helperCommon)
|
mergeConflictsHelper := helpers.NewMergeConflictsHelper(helperCommon)
|
||||||
reposHelper := helpers.NewRecentReposHelper(helperCommon, recordDirectoryHelper, gui.onNewRepo)
|
|
||||||
worktreeHelper := helpers.NewWorktreeHelper(helperCommon, reposHelper)
|
|
||||||
refreshHelper := helpers.NewRefreshHelper(
|
refreshHelper := helpers.NewRefreshHelper(
|
||||||
helperCommon,
|
helperCommon,
|
||||||
refsHelper,
|
refsHelper,
|
||||||
@ -241,6 +242,18 @@ func (gui *Gui) resetHelpersAndControllers() {
|
|||||||
controllers.AttachControllers(context, controllers.NewBasicCommitsController(common, context))
|
controllers.AttachControllers(context, controllers.NewBasicCommitsController(common, context))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, context := range []controllers.CanViewWorktreeOptions{
|
||||||
|
gui.State.Contexts.LocalCommits,
|
||||||
|
gui.State.Contexts.ReflogCommits,
|
||||||
|
gui.State.Contexts.SubCommits,
|
||||||
|
gui.State.Contexts.Stash,
|
||||||
|
gui.State.Contexts.Branches,
|
||||||
|
gui.State.Contexts.RemoteBranches,
|
||||||
|
gui.State.Contexts.Tags,
|
||||||
|
} {
|
||||||
|
controllers.AttachControllers(context, controllers.NewWorktreeOptionsController(common, context))
|
||||||
|
}
|
||||||
|
|
||||||
controllers.AttachControllers(gui.State.Contexts.ReflogCommits,
|
controllers.AttachControllers(gui.State.Contexts.ReflogCommits,
|
||||||
reflogCommitsController,
|
reflogCommitsController,
|
||||||
)
|
)
|
||||||
|
@ -204,7 +204,7 @@ func (self *BranchesController) press(selectedBranch *models.Branch) error {
|
|||||||
|
|
||||||
if selectedBranch.CheckedOutByOtherWorktree {
|
if selectedBranch.CheckedOutByOtherWorktree {
|
||||||
worktreeForRef, ok := self.worktreeForBranch(selectedBranch)
|
worktreeForRef, ok := self.worktreeForBranch(selectedBranch)
|
||||||
if ok && !self.c.Git().Worktree.IsCurrentWorktree(worktreeForRef) {
|
if ok && !self.c.Git().Worktree.IsCurrentWorktree(worktreeForRef.Path) {
|
||||||
return self.promptToCheckoutWorktree(worktreeForRef)
|
return self.promptToCheckoutWorktree(worktreeForRef)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,7 +228,7 @@ func (self *BranchesController) promptToCheckoutWorktree(worktree *models.Worktr
|
|||||||
Title: "Switch to worktree",
|
Title: "Switch to worktree",
|
||||||
Prompt: fmt.Sprintf("This branch is checked out by worktree %s. Do you want to switch to that worktree?", worktree.Name()),
|
Prompt: fmt.Sprintf("This branch is checked out by worktree %s. Do you want to switch to that worktree?", worktree.Name()),
|
||||||
HandleConfirm: func() error {
|
HandleConfirm: func() error {
|
||||||
return self.c.Helpers().Worktree.Switch(worktree, context.LOCAL_BRANCHES_CONTEXT_KEY)
|
return self.c.Helpers().Worktree.Switch(worktree.Path, context.LOCAL_BRANCHES_CONTEXT_KEY)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -346,7 +346,7 @@ func (self *BranchesController) promptWorktreeBranchDelete(selectedBranch *model
|
|||||||
{
|
{
|
||||||
Label: "Switch to worktree",
|
Label: "Switch to worktree",
|
||||||
OnPress: func() error {
|
OnPress: func() error {
|
||||||
return self.c.Helpers().Worktree.Switch(worktree, context.LOCAL_BRANCHES_CONTEXT_KEY)
|
return self.c.Helpers().Worktree.Switch(worktree.Path, context.LOCAL_BRANCHES_CONTEXT_KEY)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -9,7 +9,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
)
|
)
|
||||||
@ -66,10 +68,14 @@ func (self *WorktreeHelper) NewWorktree() error {
|
|||||||
HandleConfirm: func(path string) error {
|
HandleConfirm: func(path string) error {
|
||||||
return self.c.Prompt(types.PromptOpts{
|
return self.c.Prompt(types.PromptOpts{
|
||||||
Title: self.c.Tr.NewWorktreeBranch,
|
Title: self.c.Tr.NewWorktreeBranch,
|
||||||
HandleConfirm: func(committish string) error {
|
// TODO: suggestions
|
||||||
|
HandleConfirm: func(base string) error {
|
||||||
return self.c.WithWaitingStatus(self.c.Tr.AddingWorktree, func(gocui.Task) error {
|
return self.c.WithWaitingStatus(self.c.Tr.AddingWorktree, func(gocui.Task) error {
|
||||||
self.c.LogAction(self.c.Tr.Actions.AddWorktree)
|
self.c.LogAction(self.c.Tr.Actions.AddWorktree)
|
||||||
if err := self.c.Git().Worktree.New(sanitizedBranchName(path), committish); err != nil {
|
if err := self.c.Git().Worktree.New(git_commands.NewWorktreeOpts{
|
||||||
|
Path: path,
|
||||||
|
Base: base,
|
||||||
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.WORKTREES, types.BRANCHES, types.FILES}})
|
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.WORKTREES, types.BRANCHES, types.FILES}})
|
||||||
@ -80,14 +86,70 @@ func (self *WorktreeHelper) NewWorktree() error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *WorktreeHelper) Switch(worktree *models.Worktree, contextKey types.ContextKey) error {
|
func (self *WorktreeHelper) NewWorktreeCheckout(base string, isBranch bool, detached bool) error {
|
||||||
if self.c.Git().Worktree.IsCurrentWorktree(worktree) {
|
opts := git_commands.NewWorktreeOpts{
|
||||||
|
Base: base,
|
||||||
|
Detach: detached,
|
||||||
|
}
|
||||||
|
|
||||||
|
f := func() error {
|
||||||
|
return self.c.WithWaitingStatus(self.c.Tr.AddingWorktree, func(gocui.Task) error {
|
||||||
|
self.c.LogAction(self.c.Tr.Actions.AddWorktree)
|
||||||
|
if err := self.c.Git().Worktree.New(opts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return self.Switch(opts.Path, context.LOCAL_BRANCHES_CONTEXT_KEY)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.c.Prompt(types.PromptOpts{
|
||||||
|
Title: self.c.Tr.NewWorktreePath,
|
||||||
|
HandleConfirm: func(path string) error {
|
||||||
|
opts.Path = path
|
||||||
|
|
||||||
|
if detached {
|
||||||
|
return f()
|
||||||
|
}
|
||||||
|
|
||||||
|
if isBranch {
|
||||||
|
// prompt for the new branch name where a blank means we just check out the branch
|
||||||
|
return self.c.Prompt(types.PromptOpts{
|
||||||
|
Title: fmt.Sprintf("New branch name (leave blank to checkout %s)", base),
|
||||||
|
// TODO: suggestions
|
||||||
|
HandleConfirm: func(branchName string) error {
|
||||||
|
opts.Branch = branchName
|
||||||
|
|
||||||
|
return f()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// prompt for the new branch name where a blank means we just check out the branch
|
||||||
|
return self.c.Prompt(types.PromptOpts{
|
||||||
|
Title: "New branch name",
|
||||||
|
// TODO: suggestions
|
||||||
|
HandleConfirm: func(branchName string) error {
|
||||||
|
if branchName == "" {
|
||||||
|
return self.c.ErrorMsg("Branch name cannot be blank")
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.Branch = branchName
|
||||||
|
|
||||||
|
return f()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *WorktreeHelper) Switch(path string, contextKey types.ContextKey) error {
|
||||||
|
if self.c.Git().Worktree.IsCurrentWorktree(path) {
|
||||||
return self.c.ErrorMsg(self.c.Tr.AlreadyInWorktree)
|
return self.c.ErrorMsg(self.c.Tr.AlreadyInWorktree)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.c.LogAction(self.c.Tr.SwitchToWorktree)
|
self.c.LogAction(self.c.Tr.SwitchToWorktree)
|
||||||
|
|
||||||
return self.reposHelper.DispatchSwitchTo(worktree.Path, true, self.c.Tr.ErrWorktreeMovedOrRemoved, contextKey)
|
return self.reposHelper.DispatchSwitchTo(path, true, self.c.Tr.ErrWorktreeMovedOrRemoved, contextKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *WorktreeHelper) Remove(worktree *models.Worktree, force bool) error {
|
func (self *WorktreeHelper) Remove(worktree *models.Worktree, force bool) error {
|
||||||
@ -139,3 +201,51 @@ func (self *WorktreeHelper) Detach(worktree *models.Worktree) error {
|
|||||||
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.WORKTREES, types.BRANCHES, types.FILES}})
|
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.WORKTREES, types.BRANCHES, types.FILES}})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *WorktreeHelper) ViewWorktreeOptions(context types.IListContext, ref string) error {
|
||||||
|
if context == self.c.Contexts().Branches {
|
||||||
|
return self.ViewBranchWorktreeOptions(ref)
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.ViewRefWorktreeOptions(ref)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *WorktreeHelper) ViewBranchWorktreeOptions(branchName string) error {
|
||||||
|
return self.c.Menu(types.CreateMenuOptions{
|
||||||
|
Title: self.c.Tr.WorktreeTitle,
|
||||||
|
Items: []*types.MenuItem{
|
||||||
|
{
|
||||||
|
LabelColumns: []string{"Create new worktree from branch"},
|
||||||
|
OnPress: func() error {
|
||||||
|
return self.NewWorktreeCheckout(branchName, true, false)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LabelColumns: []string{"Create new worktree from branch (detached)"},
|
||||||
|
OnPress: func() error {
|
||||||
|
return self.NewWorktreeCheckout(branchName, true, true)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *WorktreeHelper) ViewRefWorktreeOptions(ref string) error {
|
||||||
|
return self.c.Menu(types.CreateMenuOptions{
|
||||||
|
Title: self.c.Tr.WorktreeTitle,
|
||||||
|
Items: []*types.MenuItem{
|
||||||
|
{
|
||||||
|
LabelColumns: []string{"Create new worktree from ref"},
|
||||||
|
OnPress: func() error {
|
||||||
|
return self.NewWorktreeCheckout(ref, false, false)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LabelColumns: []string{"Create new worktree from ref (detached)"},
|
||||||
|
OnPress: func() error {
|
||||||
|
return self.NewWorktreeCheckout(ref, false, true)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
59
pkg/gui/controllers/worktree_options_controller.go
Normal file
59
pkg/gui/controllers/worktree_options_controller.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This controller is for all contexts that have items you can create a worktree from
|
||||||
|
|
||||||
|
var _ types.IController = &WorktreeOptionsController{}
|
||||||
|
|
||||||
|
type CanViewWorktreeOptions interface {
|
||||||
|
types.IListContext
|
||||||
|
}
|
||||||
|
|
||||||
|
type WorktreeOptionsController struct {
|
||||||
|
baseController
|
||||||
|
c *ControllerCommon
|
||||||
|
context CanViewWorktreeOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWorktreeOptionsController(controllerCommon *ControllerCommon, context CanViewWorktreeOptions) *WorktreeOptionsController {
|
||||||
|
return &WorktreeOptionsController{
|
||||||
|
baseController: baseController{},
|
||||||
|
c: controllerCommon,
|
||||||
|
context: context,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *WorktreeOptionsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
|
bindings := []*types.Binding{
|
||||||
|
{
|
||||||
|
Key: opts.GetKey(opts.Config.Worktrees.ViewWorktreeOptions),
|
||||||
|
Handler: self.checkSelected(self.viewWorktreeOptions),
|
||||||
|
Description: self.c.Tr.ViewWorktreeOptions,
|
||||||
|
OpensMenu: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return bindings
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *WorktreeOptionsController) checkSelected(callback func(string) error) func() error {
|
||||||
|
return func() error {
|
||||||
|
ref := self.context.GetSelectedItemId()
|
||||||
|
if ref == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return callback(ref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *WorktreeOptionsController) Context() types.Context {
|
||||||
|
return self.context
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *WorktreeOptionsController) viewWorktreeOptions(ref string) error {
|
||||||
|
return self.c.Helpers().Worktree.ViewWorktreeOptions(self.context, ref)
|
||||||
|
}
|
@ -62,7 +62,7 @@ func (self *WorktreesController) GetOnRenderToMain() func() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
missing := ""
|
missing := ""
|
||||||
if self.c.Git().Worktree.IsWorktreePathMissing(worktree) {
|
if self.c.Git().Worktree.IsWorktreePathMissing(worktree.Path) {
|
||||||
missing = style.FgRed.Sprintf(" %s", self.c.Tr.MissingWorktree)
|
missing = style.FgRed.Sprintf(" %s", self.c.Tr.MissingWorktree)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ func (self *WorktreesController) remove(worktree *models.Worktree) error {
|
|||||||
return self.c.ErrorMsg(self.c.Tr.CantDeleteMainWorktree)
|
return self.c.ErrorMsg(self.c.Tr.CantDeleteMainWorktree)
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.c.Git().Worktree.IsCurrentWorktree(worktree) {
|
if self.c.Git().Worktree.IsCurrentWorktree(worktree.Path) {
|
||||||
return self.c.ErrorMsg(self.c.Tr.CantDeleteCurrentWorktree)
|
return self.c.ErrorMsg(self.c.Tr.CantDeleteCurrentWorktree)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ func (self *WorktreesController) GetOnClick() func() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *WorktreesController) enter(worktree *models.Worktree) error {
|
func (self *WorktreesController) enter(worktree *models.Worktree) error {
|
||||||
return self.c.Helpers().Worktree.Switch(worktree, context.WORKTREES_CONTEXT_KEY)
|
return self.c.Helpers().Worktree.Switch(worktree.Path, context.WORKTREES_CONTEXT_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *WorktreesController) checkSelected(callback func(worktree *models.Worktree) error) func() error {
|
func (self *WorktreesController) checkSelected(callback func(worktree *models.Worktree) error) func() error {
|
||||||
|
@ -8,11 +8,11 @@ import (
|
|||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetWorktreeDisplayStrings(worktrees []*models.Worktree, isCurrent func(*models.Worktree) bool, isMissing func(*models.Worktree) bool) [][]string {
|
func GetWorktreeDisplayStrings(worktrees []*models.Worktree, isCurrent func(string) bool, isMissing func(string) bool) [][]string {
|
||||||
return lo.Map(worktrees, func(worktree *models.Worktree, _ int) []string {
|
return lo.Map(worktrees, func(worktree *models.Worktree, _ int) []string {
|
||||||
return GetWorktreeDisplayString(
|
return GetWorktreeDisplayString(
|
||||||
isCurrent(worktree),
|
isCurrent(worktree.Path),
|
||||||
isMissing(worktree),
|
isMissing(worktree.Path),
|
||||||
worktree)
|
worktree)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -562,6 +562,7 @@ type TranslationSet struct {
|
|||||||
CreateWorktree string
|
CreateWorktree string
|
||||||
NewWorktreePath string
|
NewWorktreePath string
|
||||||
NewWorktreeBranch string
|
NewWorktreeBranch string
|
||||||
|
ViewWorktreeOptions string
|
||||||
Name string
|
Name string
|
||||||
Branch string
|
Branch string
|
||||||
Path string
|
Path string
|
||||||
@ -1286,6 +1287,7 @@ func EnglishTranslationSet() TranslationSet {
|
|||||||
CreateWorktree: "Create worktree",
|
CreateWorktree: "Create worktree",
|
||||||
NewWorktreePath: "New worktree path",
|
NewWorktreePath: "New worktree path",
|
||||||
NewWorktreeBranch: "New worktree branch (leave blank to use the current branch)",
|
NewWorktreeBranch: "New worktree branch (leave blank to use the current branch)",
|
||||||
|
ViewWorktreeOptions: "View worktree options",
|
||||||
Name: "Name",
|
Name: "Name",
|
||||||
Branch: "Branch",
|
Branch: "Branch",
|
||||||
Path: "Path",
|
Path: "Path",
|
||||||
|
Reference in New Issue
Block a user