gitbutlerapp/gitbutler · error

disabled

Error message

disabled

What it means

While rebuilding the HEAD tree across worktrees (but-core/src/repo_ext.rs), `status::Item::IndexWorktree(Rewrite)` and `TreeIndex(Change::Rewrite)` arms are `unreachable!("disabled")` because the status/diff pipeline feeding this loop is constructed with rewrite (rename/copy) detection disabled — rewrites surface as separate deletion+addition changes. The panic means some option set turned rewrite tracking back on.

Source

Thrown at crates/but-core/src/repo_ext.rs:392

                    untracked_items.push(rela_path);
                }
                status::Item::IndexWorktree(index_worktree::Item::Modification {
                    rela_path,
                    status: EntryStatus::Change(Change::SubmoduleModification(change)),
                    ..
                }) => {
                    if let Some(possibly_changed_head_commit) = change.checked_out_head_id {
                        head_tree_editor.upsert(
                            rela_path.as_bstr(),
                            gix::object::tree::EntryKind::Commit,
                            possibly_changed_head_commit,
                        )?;
                        worktreepaths_changed.insert(rela_path);
                    }
                }
                status::Item::IndexWorktree(index_worktree::Item::Rewrite { .. })
                | status::Item::TreeIndex(gix::diff::index::Change::Rewrite { .. }) => {
                    unreachable!("disabled")
                }
                status::Item::IndexWorktree(
                    index_worktree::Item::Modification {
                        status: EntryStatus::NeedsUpdate(_),
                        ..
                    }
                    | index_worktree::Item::DirectoryContents {
                        entry:
                            gix::dir::Entry {
                                status:
                                    gix::dir::entry::Status::Tracked
                                    | gix::dir::entry::Status::Pruned
                                    | gix::dir::entry::Status::Ignored(_),
                                ..
                            },
                        ..
                    },
                ) => {}

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Set rewrite tracking to `None` in the gix diff/status options used to produce items for this loop.
  2. If rewrites must stay enabled upstream, split the pipeline so the editor receives a rewrite-free item stream.
  3. Add a debug assertion/test that the item stream contains no `Rewrite` variants before the match.

Example fix

// before (options feeding the status loop)
let mut opts = gix::status::Options::default();
opts.index_worktree.rewrites = Some(gix::diff::Rewrites::default()); // enables Rewrite items

// after
let mut opts = gix::status::Options::default();
opts.index_worktree.rewrites = None; // Rewrite arms stay unreachable, as designed
Defensive patterns

Strategy: validation

Validate before calling

// ensure the status feeding the head-tree editor has rewrites off
let mut opts = gix::status::Options::default();
opts.index_worktree.rewrites = None;
opts.tree_index.rewrites = None;
let status = repo.status_with_index_stream(...)?.with_options(opts);

Prevention

When it happens

Trigger: Building the gix status platform with `rewrite: Some(...)` (rename/copy tracking enabled) and passing its items into this head-tree editor; a refactor or gix default change that flips rewrite emission on for the tree↔index or index↔worktree diff.

Common situations: Enabling rename tracking for UI purposes on a code path shared with the snapshot editor; gix dependency upgrades that alter rewrite option defaults; copy-pasting status options from another pipeline.

Related errors


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