jesseduffield/lazygit · warning

Multiple base commits found. (Try staging fewer changes at o

Error message

Multiple base commits found. (Try staging fewer changes at once)

%s

What it means

FixupHelper (pkg/gui/controllers/helpers/fixup_helper.go) implements 'find base commit for fixup': it maps changed lines back to candidate commits via blame, removes fixup commits for the last candidate, and if more than one candidate remains it fails with MultipleBaseCommitsFoundStaged/Unstaged plus the list of candidate hashes and subjects. Ambiguity, not corruption: the staged/unstaged changes span code owned by several different commits.

Source

Thrown at pkg/gui/controllers/helpers/fixup_helper.go:126

		// error. It isn't worth doing a detailed report of which commits we
		// found.
		return errors.New(self.c.Tr.BaseCommitIsAlreadyOnMainBranch)
	}

	foundCommits := getCommitsForHashes(commits, hashGroups[NOT_MERGED])
	// If there are multiple commits that could be the base commit, remove all
	// those that are fixups for the last one.
	foundCommits = removeFixupCommits(foundCommits)

	if len(foundCommits) > 1 {
		// If there are still multiple commits that could be the base commit, list
		// them in the error message. But only the candidates from the current
		// branch, not including any that are already merged.
		subjects := getHashesAndSubjects(foundCommits)
		message := lo.Ternary(hasStagedChanges,
			self.c.Tr.MultipleBaseCommitsFoundStaged,
			self.c.Tr.MultipleBaseCommitsFoundUnstaged)
		return fmt.Errorf("%s\n\n%s", message, subjects)
	}

	// Now we know that foundCommits has exactly one commit, so find its index
	_, index, _ := self.findCommit(commits, foundCommits[0].Hash())

	return self.c.ConfirmIf(warnAboutAddedLines, types.ConfirmOpts{
		Title:  self.c.Tr.FindBaseCommitForFixup,
		Prompt: self.c.Tr.HunksWithOnlyAddedLinesWarning,
		HandleConfirm: func() error {
			if !hasStagedChanges {
				if err := self.c.Git().WorkingTree.StageAll(true); err != nil {
					return err
				}
				self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.FILES}})
			}

			self.c.Contexts().LocalCommits.SetSelection(index)
			self.c.Context().Push(self.c.Contexts().LocalCommits, types.OnFocusOpts{})

View on GitHub (pinned to c477a2959b)

Solutions

  1. Stage only the changes belonging to one commit: unstage all, then stage individual hunks/lines in the staging panel and re-run fixup.
  2. Pick the intended target from the hash/subject list in the error and create a manual fixup/squash via the commit menu instead of the automatic finder.
  3. Commit the unrelated part first, then run find-base-commit again for the remainder.
Defensive patterns

Strategy: try-catch

Try / catch

// The helper surfaces ambiguity as an error; handle it by narrowing the selection:
if err := findBaseCommitForFixup(); err != nil {
	if strings.Contains(err.Error(), "Multiple base commits found") {
		// prompt user to stage fewer hunks, or pick a target from the listed candidates
	}
}

Prevention

When it happens

Trigger: Pressing the find-base-commit-for-fixup key (default 'F') on the commits view when the working-tree/staged changes touch lines last modified by two or more distinct non-fixup commits — e.g. editing two functions introduced by different commits in one file, then staging both hunks together.

Common situations: Bulk edits before remembering to fixup; staging all (a) instead of selecting hunks; mixed refactors that overlap many commits; partially reverting a change whose lines have multiple owners.

Related errors


AI-assisted analysis of jesseduffield/lazygit@c477a2959b (2026-08-15). Data as JSON: /api/errors/28487c299f9b9796. Report an issue: GitHub.