diff --git a/pkg/commands/git_commands/rebase.go b/pkg/commands/git_commands/rebase.go index 1c0497da8..188fb72cd 100644 --- a/pkg/commands/git_commands/rebase.go +++ b/pkg/commands/git_commands/rebase.go @@ -533,35 +533,15 @@ func (self *RebaseCommands) DiscardOldFileChanges(commits []*models.Commit, comm // CherryPickCommits begins an interactive rebase with the given hashes being cherry picked onto HEAD func (self *RebaseCommands) CherryPickCommits(commits []*models.Commit) error { - commitLines := lo.Map(commits, func(commit *models.Commit, _ int) string { - return fmt.Sprintf("%s %s", utils.ShortHash(commit.Hash), commit.Name) - }) - msg := utils.ResolvePlaceholderString( - self.Tr.Log.CherryPickCommits, - map[string]string{ - "commitLines": strings.Join(commitLines, "\n"), - }, - ) - self.os.LogCommand(msg, false) + hasMergeCommit := lo.SomeBy(commits, func(c *models.Commit) bool { return c.IsMerge() }) + cmdArgs := NewGitCmd("cherry-pick"). + Arg("--allow-empty"). + ArgIf(self.version.IsAtLeast(2, 45, 0), "--empty=keep", "--keep-redundant-commits"). + ArgIf(hasMergeCommit, "-m1"). + Arg(lo.Reverse(lo.Map(commits, func(c *models.Commit, _ int) string { return c.Hash }))...). + ToArgv() - return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{ - baseHashOrRoot: "HEAD", - instruction: daemon.NewCherryPickCommitsInstruction(commits), - }).Run() -} - -// CherryPickCommitsDuringRebase simply prepends the given commits to the existing git-rebase-todo file -func (self *RebaseCommands) CherryPickCommitsDuringRebase(commits []*models.Commit) error { - todoLines := lo.Map(commits, func(commit *models.Commit, _ int) daemon.TodoLine { - return daemon.TodoLine{ - Action: "pick", - Commit: commit, - } - }) - - todo := daemon.TodoLinesToString(todoLines) - filePath := filepath.Join(self.repoPaths.worktreeGitDirPath, "rebase-merge/git-rebase-todo") - return utils.PrependStrToTodoFile(filePath, []byte(todo)) + return self.cmd.New(cmdArgs).Run() } func (self *RebaseCommands) DropMergeCommit(commits []*models.Commit, commitIndex int) error { diff --git a/pkg/gui/controllers/helpers/cherry_pick_helper.go b/pkg/gui/controllers/helpers/cherry_pick_helper.go index 1cb2285d0..6b13b0fda 100644 --- a/pkg/gui/controllers/helpers/cherry_pick_helper.go +++ b/pkg/gui/controllers/helpers/cherry_pick_helper.go @@ -77,41 +77,23 @@ func (self *CherryPickHelper) Paste() error { "numCommits": strconv.Itoa(len(self.getData().CherryPickedCommits)), }), HandleConfirm: func() error { - isInRebase, err := self.c.Git().Status.IsInRebase() - if err != nil { - return err - } - if isInRebase { - if err := self.c.Git().Rebase.CherryPickCommitsDuringRebase(self.getData().CherryPickedCommits); err != nil { - return err - } - err = self.c.Refresh(types.RefreshOptions{ - Mode: types.SYNC, Scope: []types.RefreshableView{types.REBASE_COMMITS}, - }) - if err != nil { - return err - } - - return self.Reset() - } - return self.c.WithWaitingStatus(self.c.Tr.CherryPickingStatus, func(gocui.Task) error { self.c.LogAction(self.c.Tr.Actions.CherryPick) - err := self.c.Git().Rebase.CherryPickCommits(self.getData().CherryPickedCommits) - err = self.rebaseHelper.CheckMergeOrRebase(err) + result := self.c.Git().Rebase.CherryPickCommits(self.getData().CherryPickedCommits) + err := self.rebaseHelper.CheckMergeOrRebase(result) if err != nil { - return err + return result } - // If we're in an interactive rebase at this point, it must + // If we're in the cherry-picking state at this point, it must // be because there were conflicts. Don't clear the copied - // commits in this case, since we might want to abort and - // try pasting them again. - isInRebase, err = self.c.Git().Status.IsInRebase() - if err != nil { - return err + // commits in this case, since we might want to abort and try + // pasting them again. + isInCherryPick, result := self.c.Git().Status.IsInCherryPick() + if result != nil { + return result } - if !isInRebase { + if !isInCherryPick { self.getData().DidPaste = true self.rerender() } diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go index 2f001ebe4..2f0df7498 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -69,7 +69,7 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). PressPrimaryAction() - t.Common().ContinueOnConflictsResolved("rebase") + t.Common().ContinueOnConflictsResolved("cherry-pick") t.Views().Files().IsEmpty() diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_during_rebase.go b/pkg/integration/tests/cherry_pick/cherry_pick_during_rebase.go index e1fc115cf..183333754 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_during_rebase.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_during_rebase.go @@ -75,8 +75,8 @@ var CherryPickDuringRebase = NewIntegrationTest(NewIntegrationTestArgs{ }). Lines( Contains("pick CI two"), - Contains("pick CI three"), - Contains(" CI <-- YOU ARE HERE --- one"), + Contains(" CI <-- YOU ARE HERE --- three"), + Contains(" CI one"), Contains(" CI base"), ). Tap(func() {