Repository: jesseduffield/lazygit
File: pkg/gui/controllers/helpers/cherry_pick_helper.go (Go)

Code before:

	// find the last commit that is copied that's above our position
	// if there are none, startIndex = 0
	startIndex := 0
	for index, commit := range commitsList[0:selectedIndex] {
		if commitSet.Includes(commit.Sha) {
			startIndex = index
		}
	}

	for index := startIndex; index <= selectedIndex; index++ {
		commit := commitsList[index]
		self.getData().Add(commit, commitsList)
	}

	return self.rerender()
}

// HandlePasteCommits begins a cherry-pick rebase with the commits the user has copied.
// Only to be called from the branch commits controller
func (self *CherryPickHelper) Paste() error {
	return self.c.Confirm(types.ConfirmOpts{
		Title:  self.c.Tr.CherryPick,
		Prompt: self.c.Tr.SureCherryPick,
		HandleConfirm: func() error {
			if self.c.Git().Status.WorkingTreeState() != enums.REBASE_MODE_NONE {
				if err := self.c.Git().Rebase.CherryPickCommitsDuringRebase(self.getData().CherryPickedCommits); err != nil {
					return err
				}
				return self.c.Refresh(types.RefreshOptions{
					Mode: types.SYNC, Scope: []types.RefreshableView{types.REBASE_COMMITS},
				})
			}

			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)
				return self.rebaseHelper.CheckMergeOrRebase(err)
			})
		},
	})
}

func (self *CherryPickHelper) Reset() error {
	self.getData().ContextKey = ""
	self.getData().CherryPickedCommits = nil

	return self.rerender()
}

// you can only copy from one context at a time, because the order and position of commits matter

Review comment (suggestion):
I assume this won't work for `REBASE_MODE_MERGING` due to the lack of a todo file.

In fact, workingTreeState doesn't distinguish between interactive and non-interactive rebases:

```go
func (self *StatusCommands) WorkingTreeState() enums.RebaseMode {
	rebaseMode, _ := self.RebaseMode()
	if rebaseMode != enums.REBASE_MODE_NONE {
		return enums.REBASE_MODE_REBASING
	}
	merging, _ := self.IsInMergeState()
	if merging {
		return enums.REBASE_MODE_MERGING
	}
	return enums.REBASE_MODE_NONE
}
```

But we only want to do this for interactive rebases because those are the ones with todo files.

Sounds like we need a `self.c.Git().Status.InInteractiveRebase()`

Code after:
	// find the last commit that is copied that's above our position
	// if there are none, startIndex = 0
	startIndex := 0
	for index, commit := range commitsList[0:selectedIndex] {
		if commitSet.Includes(commit.Sha) {
			startIndex = index
		}
	}

	for index := startIndex; index <= selectedIndex; index++ {
		commit := commitsList[index]
		self.getData().Add(commit, commitsList)
	}

	return self.rerender()
}

// HandlePasteCommits begins a cherry-pick rebase with the commits the user has copied.
// Only to be called from the branch commits controller
func (self *CherryPickHelper) Paste() error {
	return self.c.Confirm(types.ConfirmOpts{
		Title:  self.c.Tr.CherryPick,
		Prompt: self.c.Tr.SureCherryPick,
		HandleConfirm: func() error {
			isInRebase, err := self.c.Git().Status.IsInInteractiveRebase()
			if err != nil {
				return err
			}
			if isInRebase {
				if err := self.c.Git().Rebase.CherryPickCommitsDuringRebase(self.getData().CherryPickedCommits); err != nil {
					return err
				}
				return self.c.Refresh(types.RefreshOptions{
					Mode: types.SYNC, Scope: []types.RefreshableView{types.REBASE_COMMITS},
				})
			}

			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)
				return self.rebaseHelper.CheckMergeOrRebase(err)
			})
		},
	})
}

func (self *CherryPickHelper) CanPaste() bool {
	return self.getData().Active()
}

func (self *CherryPickHelper) Reset() error {