diff --git a/pkg/gui/controllers.go b/pkg/gui/controllers.go index c883c3cc5..c02d6bae2 100644 --- a/pkg/gui/controllers.go +++ b/pkg/gui/controllers.go @@ -45,7 +45,8 @@ func (gui *Gui) resetHelpersAndControllers() { patchBuildingHelper := helpers.NewPatchBuildingHelper(helperCommon) stagingHelper := helpers.NewStagingHelper(helperCommon) mergeConflictsHelper := helpers.NewMergeConflictsHelper(helperCommon) - worktreeHelper := helpers.NewWorktreeHelper(helperCommon) + reposHelper := helpers.NewRecentReposHelper(helperCommon, recordDirectoryHelper, gui.onNewRepo) + worktreeHelper := helpers.NewWorktreeHelper(helperCommon, reposHelper) refreshHelper := helpers.NewRefreshHelper( helperCommon, refsHelper, @@ -94,7 +95,7 @@ func (gui *Gui) resetHelpersAndControllers() { Commits: commitsHelper, Snake: helpers.NewSnakeHelper(helperCommon), Diff: diffHelper, - Repos: helpers.NewRecentReposHelper(helperCommon, recordDirectoryHelper, gui.onNewRepo), + Repos: reposHelper, RecordDirectory: recordDirectoryHelper, Update: helpers.NewUpdateHelper(helperCommon, gui.Updater), Window: windowHelper, diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index a1a791805..e74e2abb8 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -202,10 +202,37 @@ func (self *BranchesController) press(selectedBranch *models.Branch) error { return self.c.ErrorMsg(self.c.Tr.AlreadyCheckedOutBranch) } + if selectedBranch.CheckedOutByOtherWorktree { + worktreeForRef, ok := self.worktreeForRef(selectedBranch.Name) + if ok && !self.c.Git().Worktree.IsCurrentWorktree(worktreeForRef) { + return self.promptToCheckoutWorktree(worktreeForRef) + } + } + self.c.LogAction(self.c.Tr.Actions.CheckoutBranch) return self.c.Helpers().Refs.CheckoutRef(selectedBranch.Name, types.CheckoutRefOptions{}) } +func (self *BranchesController) worktreeForRef(ref string) (*models.Worktree, bool) { + for _, worktree := range self.c.Model().Worktrees { + if worktree.Branch == ref { + return worktree, true + } + } + + return nil, false +} + +func (self *BranchesController) promptToCheckoutWorktree(worktree *models.Worktree) error { + return self.c.Confirm(types.ConfirmOpts{ + 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()), + HandleConfirm: func() error { + return self.c.Helpers().Worktree.Switch(worktree) + }, + }) +} + func (self *BranchesController) handleCreatePullRequest(selectedBranch *models.Branch) error { return self.createPullRequest(selectedBranch.Name, "") } diff --git a/pkg/gui/controllers/helpers/worktree_helper.go b/pkg/gui/controllers/helpers/worktree_helper.go index a05d469ce..888838370 100644 --- a/pkg/gui/controllers/helpers/worktree_helper.go +++ b/pkg/gui/controllers/helpers/worktree_helper.go @@ -18,12 +18,14 @@ type IWorktreeHelper interface { } type WorktreeHelper struct { - c *HelperCommon + c *HelperCommon + reposHelper *ReposHelper } -func NewWorktreeHelper(c *HelperCommon) *WorktreeHelper { +func NewWorktreeHelper(c *HelperCommon, reposHelper *ReposHelper) *WorktreeHelper { return &WorktreeHelper{ - c: c, + c: c, + reposHelper: reposHelper, } } @@ -75,3 +77,17 @@ func (self *WorktreeHelper) NewWorktree() error { }, }) } + +func (self *WorktreeHelper) Switch(worktree *models.Worktree) error { + if self.c.Git().Worktree.IsCurrentWorktree(worktree) { + return self.c.ErrorMsg(self.c.Tr.AlreadyInWorktree) + } + + self.c.LogAction(self.c.Tr.SwitchToWorktree) + + // if we were in a submodule, we want to forget about that stack of repos + // so that hitting escape in the new repo does nothing + self.c.State().GetRepoPathStack().Clear() + + return self.reposHelper.DispatchSwitchTo(worktree.Path, true, self.c.Tr.ErrWorktreeMovedOrDeleted) +} diff --git a/pkg/gui/controllers/worktrees_controller.go b/pkg/gui/controllers/worktrees_controller.go index c8b23f906..3c5d5f381 100644 --- a/pkg/gui/controllers/worktrees_controller.go +++ b/pkg/gui/controllers/worktrees_controller.go @@ -34,7 +34,7 @@ func (self *WorktreesController) GetKeybindings(opts types.KeybindingsOpts) []*t { Key: opts.GetKey(opts.Config.Universal.Select), Handler: self.checkSelected(self.enter), - Description: self.c.Tr.EnterWorktree, + Description: self.c.Tr.SwitchToWorktree, }, { Key: opts.GetKey(opts.Config.Universal.Remove), @@ -143,15 +143,7 @@ func (self *WorktreesController) GetOnClick() func() error { } func (self *WorktreesController) enter(worktree *models.Worktree) error { - if self.c.Git().Worktree.IsCurrentWorktree(worktree) { - return self.c.ErrorMsg(self.c.Tr.AlreadyInWorktree) - } - - // if we were in a submodule, we want to forget about that stack of repos - // so that hitting escape in the new repo does nothing - self.c.State().GetRepoPathStack().Clear() - - return self.c.Helpers().Repos.DispatchSwitchTo(worktree.Path, true, self.c.Tr.ErrWorktreeMovedOrDeleted) + return self.c.Helpers().Worktree.Switch(worktree) } func (self *WorktreesController) checkSelected(callback func(worktree *models.Worktree) error) func() error { diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 049bf9e11..ba3707642 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -542,7 +542,7 @@ type TranslationSet struct { FilterPrefix string ExitSearchMode string ExitTextFilterMode string - EnterWorktree string + SwitchToWorktree string RemoveWorktree string RemoveWorktreeTitle string WorktreesTitle string @@ -1266,7 +1266,7 @@ func EnglishTranslationSet() TranslationSet { FilterPrefix: "Filter: ", WorktreesTitle: "Worktrees", WorktreeTitle: "Worktree", - EnterWorktree: "Enter worktree", + SwitchToWorktree: "Switch to worktree", RemoveWorktree: "Remove worktree", RemoveWorktreeTitle: "Remove worktree", RemoveWorktreePrompt: "Are you sure you want to remove worktree '{{.worktreeName}}'?",