jesseduffield/lazygit · warning

Cannot fast-forward a branch with no upstream

Error message

Cannot fast-forward a branch with no upstream

What it means

Returned by BranchesController.fastForward (branches_controller.go:660) via Tr.FwdNoUpstream. Fast-forwarding means moving a local branch to its upstream's tip; without tracking config (IsTrackingRemote() false) there is no upstream to pull from, so the operation is rejected before the WithInlineStatus task starts. Sibling guards cover the related cases: no locally stored remote ref (FwdNoLocalUpstream) and commits already ahead (FwdCommitsToPush).

Source

Thrown at pkg/gui/controllers/branches_controller.go:660

	return self.c.Menu(types.CreateMenuOptions{
		Title: menuTitle,
		Items: []*types.MenuItem{localDeleteItem, remoteDeleteItem, deleteBothItem},
	})
}

func (self *BranchesController) merge() error {
	selectedBranchName := self.context().GetSelected().Name
	return self.c.Helpers().MergeAndRebase.MergeRefIntoCheckedOutBranch(selectedBranchName)
}

func (self *BranchesController) rebase(branch *models.Branch) error {
	return self.c.Helpers().MergeAndRebase.RebaseOntoRef(branch.Name)
}

func (self *BranchesController) fastForward(branch *models.Branch) error {
	if !branch.IsTrackingRemote() {
		return errors.New(self.c.Tr.FwdNoUpstream)
	}
	if !branch.RemoteBranchStoredLocally() {
		return errors.New(self.c.Tr.FwdNoLocalUpstream)
	}
	if branch.IsAheadForPull() {
		return errors.New(self.c.Tr.FwdCommitsToPush)
	}

	action := self.c.Tr.Actions.FastForwardBranch
	worktree, ok := self.worktreeForBranch(branch)

	return self.c.WithInlineStatus(branch, types.ItemOperationFastForwarding, context.LOCAL_BRANCHES_CONTEXT_KEY, func(task gocui.Task) error {
		if ok {
			self.c.LogAction(action)

			worktreeGitDir := ""
			worktreePath := ""
			// if it is the current worktree path, no need to specify the path

View on GitHub (pinned to c477a2959b)

Solutions

  1. Push with upstream tracking: 'git push -u origin <branch>', after which fast-forward becomes meaningful (or is unnecessary)
  2. Set the upstream to an existing remote branch: 'git branch --set-upstream-to=origin/<branch> <branch>'
  3. If you meant to update from another branch, use merge (M) or rebase (r) instead

Example fix

# shell fix
git branch --set-upstream-to=origin/$(git branch --show-current) $(git branch --show-current)
# then 'f' works in lazygit
Defensive patterns

Strategy: validation

Validate before calling

func canFastForward(b *models.Branch) error {
    if !b.IsTrackingRemote() {
        return errors.New("branch has no upstream")
    }
    if !b.RemoteBranchStoredLocally() {
        return errors.New("upstream ref not fetched locally; run fetch first")
    }
    if b.IsAheadForPull() {
        return errors.New("branch has commits to push; fast-forward not applicable")
    }
    return nil
}

Type guard

func isFastForwardable(b *models.Branch) bool {
    return b.IsTrackingRemote() && b.RemoteBranchStoredLocally() && !b.IsAheadForPull()
}

Prevention

When it happens

Trigger: Pressing 'f' (fast-forward) on a branch in the local branches panel that has no upstream configured — typically a newly created local branch.

Common situations: Branches created locally and not yet pushed; upstream lost after a remote refactor; fresh clones with partial refspecs where un-checked-out branches have no tracking.

Related errors


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