diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 32fd7718e..7659a5f00 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -73,6 +73,11 @@ type Gui struct { CustomCommandsClient *custom_commands.Client + // Unlike the other modes, the cherry-picking mode is shared by all repo + // states, so that you can copy commits in one worktree or repo and paste + // them in another. + cherryPicking *cherrypicking.CherryPicking + // this is a mapping of repos to gui states, so that we can restore the original // gui state when returning from a subrepo. // In repos with multiple worktrees, we store a separate repo state per worktree. @@ -647,7 +652,7 @@ func (gui *Gui) resetState(startArgs appTypes.StartArgs) types.Context { }, Modes: &types.Modes{ Filtering: filtering.New(startArgs.FilterPath, ""), - CherryPicking: cherrypicking.New(), + CherryPicking: gui.cherryPicking, Diffing: diffing.New(), MarkedBaseCommit: marked_base_commit.New(), }, @@ -800,6 +805,7 @@ func NewGui( showRecentRepos: showRecentRepos, RepoPathStack: &utils.Stack[types.RepoLocation]{}, RepoStateMap: map[Repo]*GuiRepoState{}, + cherryPicking: cherrypicking.New(), GuiLog: []string{}, // initializing this to true for the time being; it will be reset to the diff --git a/pkg/gui/types/modes.go b/pkg/gui/types/modes.go index a11ed0081..10bdceb63 100644 --- a/pkg/gui/types/modes.go +++ b/pkg/gui/types/modes.go @@ -9,7 +9,7 @@ import ( type Modes struct { Filtering filtering.Filtering - CherryPicking *cherrypicking.CherryPicking + CherryPicking *cherrypicking.CherryPicking // shared by all repo states; see Gui.cherryPicking Diffing diffing.Diffing MarkedBaseCommit marked_base_commit.MarkedBaseCommit } diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_across_worktrees.go b/pkg/integration/tests/cherry_pick/cherry_pick_across_worktrees.go new file mode 100644 index 000000000..1e6abf18c --- /dev/null +++ b/pkg/integration/tests/cherry_pick/cherry_pick_across_worktrees.go @@ -0,0 +1,79 @@ +package cherry_pick + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var CherryPickAcrossWorktrees = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Copy commits in one worktree, drop them there, and paste them in another worktree", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell. + EmptyCommit("base"). + AddWorktree("master", "../linked-worktree", "newbranch"). + EmptyCommit("one"). + EmptyCommit("two") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + Lines( + Contains("two").IsSelected(), + Contains("one"), + Contains("base"), + ). + Press(keys.Universal.RangeSelectDown). + Press(keys.Commits.CherryPickCopy). + Tap(func() { + t.Views().Information().Content(Contains("2 commits copied")) + }). + Press(keys.Universal.Remove). + Tap(func() { + t.ExpectPopup().Confirmation(). + Title(Equals("Drop commit")). + Content(Contains("Are you sure you want to drop the selected commit(s)?")). + Confirm() + }). + Lines( + Contains("base").IsSelected(), + ) + + t.Views().Branches(). + Focus(). + NavigateToLine(Contains("newbranch")). + Press(keys.Universal.Select). + Tap(func() { + t.ExpectPopup().Confirmation(). + Title(Equals("Switch to worktree")). + Content(Equals("This branch is checked out by worktree linked-worktree. Do you want to switch to that worktree?")). + Confirm() + }). + Lines( + Contains("newbranch").IsSelected(), + Contains("master (worktree repo)"), + ) + + t.Views().Information().Content(Contains("2 commits copied")) + + t.Views().Commits(). + Focus(). + Lines( + Contains("base").IsSelected(), + ). + Press(keys.Commits.PasteCommits). + Tap(func() { + t.ExpectPopup().Alert(). + Title(Equals("Cherry-pick")). + Content(Contains("Are you sure you want to cherry-pick the 2 copied commit(s) onto this branch?")). + Confirm() + }). + Lines( + Contains("two"), + Contains("one"), + Contains("base").IsSelected(), + ) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index 7a5c728ba..29d18db02 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -93,6 +93,7 @@ var tests = []*components.IntegrationTest{ branch.Suggestions, branch.UnsetUpstream, cherry_pick.CherryPick, + cherry_pick.CherryPickAcrossWorktrees, cherry_pick.CherryPickCommitThatBecomesEmpty, cherry_pick.CherryPickConflicts, cherry_pick.CherryPickConflictsEmptyCommitAfterResolving,