GitoxideLabs/gitoxide · error
the current checkout has a pending rebase; time-travel to…
Error message
the current checkout has a pending rebase; time-travel to HEAD before editing it
What it means
`reject_pending_checkout_path` walks from a commit id up its first-parent chain and fails if any ancestor is a pending rebase commit. The currently checked-out history contains an unfinished (pending) rebase; editing it requires first time-traveling back to HEAD, otherwise the edit would operate on provisional rebase state.
Solutions
- Time-travel back to HEAD (abandon/complete the pending rebase checkout) before running the edit, as the message instructs.
- Complete the in-progress rebase (resolve conflicts and continue) then retry the edit.
- Abort the pending rebase, then re-run the edit operation.
- Pick a different target commit that is not on a pending rebase path.
Example fix
// before: editing while a pending rebase is checked out edit.perform(repo, target_id)?; // bails // after: return to HEAD first time_travel_to_head(repo)?; // restore checkout to HEAD edit.perform(repo, target_id)?;
Defensive patterns
Strategy: validation
Validate before calling
// walk first-parent chain from the edit target before editing
let mut id = target_id;
let mut seen = std::collections::HashSet::new();
while seen.insert(id) {
let c = repo.find_commit(id)?.decode()?.into_owned()?;
if gix_tix::edit::rebase::is_pending(&c) { time_travel_to_head(repo)?; break; }
match c.parents.first().copied() { Some(p) => id = p, None => break }
}
Try / catch
match edit::perform(repo, target_id) {
Err(e) if e.to_string().contains("pending rebase") => {
time_travel_to_head(repo)?;
edit::perform(repo, target_id)
}
other => other,
}
Prevention
- Finish or abort in-progress rebases before running edit tooling
- Restore checkout to HEAD before scripted edits
- Avoid running edits from detached/pending rebase checkouts
When it happens
Trigger: Any edit operation that resolves a checkout path via `reject_pending_checkout_path` when walking `commit.parents.first()` reaches a commit for which `is_pending()` is true — i.e. the commit chain being edited includes a pending rebase commit reachable from the current checkout.
Common situations: User is in the middle of an interactive rebase (detached pending commits exist) and tries to run an edit/undo/rewrite command against an ancestor; automation scripts invoked while a rebase is paused mid-conflict.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- the root of a repeated rebase must be pending
- the parent of a repeated rebase must not be pending
- has a pending rebase
- the rebase state contains duplicate scope commits
- the rebase state contains duplicate tips
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/387a3d96e81a4df9.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/rebase.rs:2571
}
}
}
if repeat
&& let Some(base) = affected.first()
&& let Some(parent) = graph.parents_of(*base).and_then(|parents| parents.first().copied())
&& is_pending(&repo.find_commit(parent)?.decode()?.into_owned()?)
{
anyhow::bail!("the parent of a repeated rebase must not be pending");
}
Ok(())
}
fn reject_pending_checkout_path(repo: &gix::Repository, mut id: ObjectId) -> Result<()> {
let mut seen = HashSet::new();
while seen.insert(id) {
let commit = repo.find_commit(id)?.decode()?.into_owned()?;
if is_pending(&commit) {
anyhow::bail!("the current checkout has a pending rebase; time-travel to HEAD before editing it");
}
let Some(parent) = commit.parents.first().copied() else {
break;
};
id = parent;
}
Ok(())
}
enum TreeRewrite {
Complete(ObjectId),
Conflict {
ours: ObjectId,
merged: ObjectId,
conflicts: Vec<gix::merge::tree::Conflict>,
},
}
View on GitHub (pinned to e73179060b)