gitbutlerapp/gitbutler · error · anyhow::Error

Need to specify a rev-spec of form `a..b` to indicate an exc

Error message

Need to specify a rev-spec of form `a..b` to indicate an exclusion for now.

What it means

In `but revision log`, even after a spec parses, the traversal step currently only implements `find_commit_ids_reachable_from_a_not_b`, which requires an excluded endpoint. A single-commit `Spec::Include` reaches this else-branch and bails: for now the command requires the `a..b` form. It's a temporary implementation limit, stated explicitly by the message.

Source

Thrown at crates/but-debug/src/command/revision.rs:68

    let mut graph_commits = vec![included];
    graph_commits.extend(excluded);

    let graph_tips = args_to_tips(repo, &log_args.graph)?;
    let graph = {
        let _span =
            tracing::info_span!("build graph", commit_count = graph_commits.len()).entered();
        graph_for_revisions(repo, meta, &graph_commits, graph_tips)?
    };

    let _span = tracing::info_span!("traverse graph").entered();
    let commits = if let Some(excluded) = excluded {
        graph.find_commit_ids_reachable_from_a_not_b(
            included,
            excluded,
            FirstParent::from(log_args.first_parent),
        )?
    } else {
        bail!("Need to specify a rev-spec of form `a..b` to indicate an exclusion for now.")
    };

    let mut out = io::BufWriter::new(out);
    for commit_id in commits {
        commit_id.write_hex_to(&mut out)?;
        writeln!(out)?;
    }
    Ok(())
}

fn merge_base(
    repo: &gix::Repository,
    meta: &EmptyRefMetadata,
    merge_base_args: &MergeBaseArgs,
    out: &mut dyn io::Write,
) -> Result<()> {
    let commits = {
        let _span = tracing::info_span!(

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Always pass a range: `but revision log main..HEAD`.
  2. Pick an explicit base you want excluded (parent, main, tag) for the left side of `..`.
  3. For plain single-commit inspection, use git itself (`git show <rev>`) or other but subcommands until the command supports Include specs.

Example fix

# before
but revision log HEAD

# after
but revision log main..HEAD
Defensive patterns

Strategy: validation

Validate before calling

# Shell — enforce the a..b form up front
if ! [[ "$1" == *..* ]]; then
  echo "revision log currently requires a range like main..HEAD" >&2
  exit 2
fi
but revision log "$1"

Prevention

When it happens

Trigger: Running `but revision log <single-rev>` (e.g. `but revision log HEAD`) — the spec parses as `Spec::Include` with no `excluded`, so traversal refuses.

Common situations: Expecting `git log <rev>` behavior from `but revision log`; scripts calling it with one revision.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/3148161155760b9b. Report an issue: GitHub.