gitbutlerapp/gitbutler · error

No commits were provided to squash

Error message

No commits were provided to squash

What it means

commit_squash_only_with_perm (the squash entry point behind the but-api squash surface) validates up front that subject_commit_ids is non-empty; an empty selection means there is nothing to fold into the target commit, so it bails before opening the workspace or creating an Editor.

Source

Thrown at crates/but-api/src/commit/squash.rs:54

        guard.write_permission(),
    )
}

/// Squash `subject_commit_ids` into `target_commit_id` under caller-held
/// exclusive repository access.
///
/// This variant does not create an oplog entry. When `dry_run` is enabled, it
/// returns a preview of the resulting workspace state without materializing the rebases.
pub fn commit_squash_only_with_perm(
    ctx: &mut but_ctx::Context,
    subject_commit_ids: Vec<gix::ObjectId>,
    target_commit_id: gix::ObjectId,
    how_to_combine_messages: MessageCombinationStrategy,
    dry_run: DryRun,
    perm: &mut RepoExclusive,
) -> anyhow::Result<CommitSquashResult> {
    if subject_commit_ids.is_empty() {
        anyhow::bail!("No commits were provided to squash")
    }
    let mut meta = ctx.meta()?;
    let (repo, mut ws, mut db) = ctx.workspace_mut_and_db_mut_with_perm(perm)?;
    let editor = Editor::create(&mut ws, &mut meta, &repo, &mut db)?;
    let SquashCommitsOutcome {
        rebase,
        commit_selector,
    } = but_workspace::commit::squash_commits(
        editor,
        subject_commit_ids,
        target_commit_id,
        how_to_combine_messages,
    )?;
    let new_commit = rebase.lookup_pick(commit_selector)?;
    let workspace = WorkspaceState::from_successful_rebase(rebase, &repo, dry_run)?;

    Ok(CommitSquashResult {
        new_commit,

View on GitHub (pinned to 2497b8007a)

Solutions

  1. Pass at least one commit id to squash into the target commit.
  2. Guard the caller: treat an empty selection as a no-op or disable the action instead of invoking the API.
  3. In UIs, require a non-empty selection before enabling squash.

Example fix

// before
but_api::commit_squash_only_with_perm(ctx, vec![], target_id, how, DryRun::No, perm)?;

// after
if !subject_commit_ids.is_empty() {
    but_api::commit_squash_only_with_perm(ctx, subject_commit_ids, target_id, how, DryRun::No, perm)?;
}
Defensive patterns

Strategy: validation

Validate before calling

fn can_squash(subject_commit_ids: &[gix::ObjectId]) -> bool {
    !subject_commit_ids.is_empty()
}

Prevention

When it happens

Trigger: Calling commit_squash_only_with_perm or its but-api wrapper with an empty Vec<gix::ObjectId> — typically a UI passing an empty multi-selection or a script computing a commit list from a filter that matched nothing.

Common situations: Frontends not disabling the squash action with nothing selected; batch pipelines looping over zero matched commits; selection state lost before the call.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17). Data as JSON: /api/errors/5627b88d117791bf. Report an issue: GitHub.