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

Code before:
		if err != nil {
			return err
		}
		return self.c.ErrorMsg("Multiple base commits found. (" +
			lo.Ternary(useIndex, "Try staging fewer changes", "Try staging some of the changes") +
			")\n\n" + subjects)
	}

	commit, index, ok := lo.FindIndexOf(self.c.Model().Commits, func(commit *models.Commit) bool {
		return commit.Sha == shas[0]
	})
	if !ok {
		if self.c.Model().Commits[len(self.c.Model().Commits)-1].Status == models.StatusMerged {
			// If the commit is not found, it's most likely because it's already
			// merged, and more than 300 commits away. Check if the last known
			// commit is already merged; if so, show the "already merged" error.
			return self.c.ErrorMsg("The base commit for this change is already on master")
		}
		// If we get here, the current branch must have more then 300 commits. Unlikely...
		return self.c.ErrorMsg("Base commit is not in current view")
	}
	if commit.Status == models.StatusMerged {
		return self.c.ErrorMsg("The base commit for this change is already on master")
	}

	if !useIndex {
		if err := self.c.Git().WorkingTree.StageAll(); err != nil {
			return err
		}
		_ = self.c.Refresh(types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{types.FILES}})
	}

	self.c.Contexts().LocalCommits.SetSelectedLineIdx(index)
	return self.c.PushContext(self.c.Contexts().LocalCommits)
}

func (self *FixupHelper) getDiff() (string, bool, error) {
	args := []string{"-U0", "--ignore-submodules=all", "HEAD", "--"}

	// Try staged changes first
	useIndex := true
	diff, err := self.c.Git().Diff.DiffIndexCmdObj(append([]string{"--cached"}, args...)...).RunWithOutput()

	if err == nil && diff == "" {
		useIndex = false
		// If there are no staged changes, try unstaged changes
		diff, err = self.c.Git().Diff.DiffIndexCmdObj(args...).RunWithOutput()
	}

	return diff, useIndex, err
}

Review comment (suggestion):
Took me a bit to make sense of this part: would be good to add a comment saying something like 'If there are no existing staged changes, then we assume the user intends to amend the commit with all files, so we stage them before focusing the commits view'.

In fact I'd change `useIndex` to be named `noStagedChanges` to make this clearer. 

Code after:
		if err != nil {
			return err
		}
		message := lo.Ternary(hasStagedChanges,
			self.c.Tr.MultipleBaseCommitsFoundStaged,
			self.c.Tr.MultipleBaseCommitsFoundUnstaged)
		return self.c.ErrorMsg(message + "\n\n" + subjects)
	}

	commit, index, ok := lo.FindIndexOf(self.c.Model().Commits, func(commit *models.Commit) bool {
		return commit.Sha == shas[0]
	})
	if !ok {
		commits := self.c.Model().Commits
		if commits[len(commits)-1].Status == models.StatusMerged {
			// If the commit is not found, it's most likely because it's already
			// merged, and more than 300 commits away. Check if the last known
			// commit is already merged; if so, show the "already merged" error.
			return self.c.ErrorMsg(self.c.Tr.BaseCommitIsAlreadyOnMainBranch)
		}
		// If we get here, the current branch must have more then 300 commits. Unlikely...
		return self.c.ErrorMsg(self.c.Tr.BaseCommitIsNotInCurrentView)
	}
	if commit.Status == models.StatusMerged {
		return self.c.ErrorMsg(self.c.Tr.BaseCommitIsAlreadyOnMainBranch)
	}

	doIt := func() error {
		if !hasStagedChanges {
			if err := self.c.Git().WorkingTree.StageAll(); err != nil {
				return err
			}
			_ = self.c.Refresh(types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{types.FILES}})
		}

		self.c.Contexts().LocalCommits.SetSelectedLineIdx(index)
		return self.c.PushContext(self.c.Contexts().LocalCommits)
	}

	if hasHunksWithOnlyAddedLines {
		return self.c.Confirm(types.ConfirmOpts{
			Title:  self.c.Tr.FindBaseCommitForFixup,
			Prompt: self.c.Tr.HunksWithOnlyAddedLinesWarning,
			HandleConfirm: func() error {
				return doIt()
			},
		})
	}

	return doIt()
}