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
- Set rewrite tracking to `None` in the gix diff/status options used to produce items for this loop.
- If rewrites must stay enabled upstream, split the pipeline so the editor receives a rewrite-free item stream.
- 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
- Keep one status/options constructor for snapshot/editor pipelines with rewrites set to None.
- Never share a rename-aware diff platform with code matching on status items exhaustively.
- Add a debug assertion that the item stream contains no Rewrite variants before the editor loop.
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
- BUG: this must have been deactivated
- we never return these as the status iteration is configured
- BUG: we use 'matching' so there are no directories
- BUG: `gix` disables this, as it knows we always need to be a
- worktree-changes are always set if there are hunks
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/c5caa5ecf982d26c.
Report an issue: GitHub.