GitoxideLabs/gitoxide · error
could not inspect a reference before rebasing
Error message
could not inspect a reference before rebasing: {err} What it means
Before performing a rebase, the code snapshots all references it may need for undo/restore. If reading a reference returns an unexpected error that is not simply a missing reference (which is tolerated via `continue`), the operation aborts with this contextual message wrapping `{err}`.
Solutions
- Inspect the wrapped `{err}` in the message to identify the underlying ref error and fix the repository state (e.g. remove stale `.lock` files).
- Run `git fsck` / `git pack-refs --all` to repair or consolidate refs.
- Delete or repair the specific broken ref file under `.git/refs`/packed-refs.
- Retry the rebase after no other git process is concurrently writing refs.
Example fix
// after diagnosing the wrapped err
let stale = repo.git_dir().join("refs/heads/broken.lock");
if stale.exists() { std::fs::remove_file(&stale).ok(); }
repo.references()?.all()?.for_each(|r| { let _ = r?; Ok::<_, anyhow::Error>(()) })?; // verify all readable
edit.rebase(...)?; Defensive patterns
Strategy: try-catch
Validate before calling
// ensure every ref is readable before rebasing
for refr in repo.references()?.all()? {
refr.map_err(|e| anyhow::anyhow!("unreadable ref before rebase: {e}"))??;
}
Try / catch
match edit::rebase::perform(repo, plan) {
Err(e) if e.to_string().contains("could not inspect a reference") => {
repair_refs(repo)?; // e.g. drop stale .lock files, pack-refs
edit::rebase::perform(repo, plan)
}
other => other,
}
Prevention
- Avoid running ref-writing git processes concurrently with edits
- Clean stale `*.lock` files under `.git/refs` after crashes
- Periodically run `git fsck` to catch ref corruption early
When it happens
Trigger: Calling a rebase edit when `repo.references()?.all()?` yields a reference whose `reference.name()` / peeling returns a real `Err` other than a missing-reference error (e.g. corrupt ref file, unreadable packed-refs entry, lock contention).
Common situations: Repositories with partially corrupted or hand-edited `.git/refs` files; concurrent git processes leaving stale `.lock` files; network remotes whose refs cannot be read at rebase time.
Understand the failure class
Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.
Related errors
- could not persist a prepared rebase object
- could not read local branch
- could not read reference
- One or more errors occurred - checkout is incomplete
- rebase todo requires at least one -x/--hide revision when…
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/2498803d65afa307.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/rebase.rs:2987
if old == new {
continue;
}
if let (Some(old), Some(new)) = (old, new) {
ref_rewrites.push(RefRewrite {
name: name.clone(),
old,
new,
});
}
edits.push(ref_edit(name.clone(), old, new));
rollback.push(ref_edit(name, new, old));
}
} else if !unborn {
for reference in repo.references()?.all()? {
let reference = match reference {
Ok(reference) => reference,
Err(err) if is_missing_ref(&*err) => continue,
Err(err) => anyhow::bail!("could not inspect a reference before rebasing: {err}"),
};
if matches!(
reference.name().category(),
Some(Category::Tag | Category::RemoteBranch)
) || super::undo::is_queue_ref(reference.name().as_bstr())
{
continue;
}
let Some(old) = reference.try_id().map(gix::Id::detach) else {
continue;
};
let Some(new) = rewritten.get(&old) else { continue };
let name = reference.name().to_owned();
if delete_refs.iter().any(|(delete, _)| delete == &name) {
continue;
}
if let Some(new) = *new {
ref_rewrites.push(RefRewrite {View on GitHub (pinned to e73179060b)