GitoxideLabs/gitoxide · error
cannot time-travel from an unborn HEAD
Error message
cannot time-travel from an unborn HEAD
What it means
Time travel cannot start because HEAD is unborn: the repository has no commits (HEAD points at a branch that does not exist yet), so `head.id()` returns None. The library bails since there is no commit to travel from. Thrown at the start of `perform_reporting_rebased`.
Solutions
- Create an initial commit before time-traveling (`git commit --allow-empty` if appropriate).
- Check out a branch that has at least one commit.
- Verify with `git rev-parse HEAD` (must not error) before invoking the operation.
Example fix
// before (fresh repo) $ gix time-travel ... # unborn HEAD // after $ git commit --allow-empty -m "initial" $ gix time-travel ...
Defensive patterns
Strategy: validation
Validate before calling
let repo = gix::open(repo_path)?;
let head = repo.head()?;
if head.is_unborn() || head.id().is_none() {
return Err(anyhow!("repository has no commits; create an initial commit first"));
} Type guard
fn head_is_born(repo: &gix::Repository) -> bool {
repo.head().ok().and_then(|h| h.id()).is_some()
} Try / catch
match result {
Err(e) if e.to_string().contains("cannot time-travel from an unborn HEAD") => {
// create an initial commit, then retry
}
other => other?,
} Prevention
- Skip time-travel tooling on freshly initialized repositories.
- Verify `git rev-parse HEAD` succeeds before invoking.
- Avoid orphan branches with zero commits as starting points.
When it happens
Trigger: Calling perform (or the listed tests) on a freshly `git init`-ed repository before the first commit, or on a repo whose current branch has no commits, so `head.id()` is None and the `let ... else` bails.
Common situations: Running the tool right after initializing a repo; an orphan branch checkout with no commits; a repo where the initial commit failed and the branch never materialized.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- cannot restore an unborn checkout after review setup failed
- cannot split with unresolved conflicts
- splitting requires both staged and worktree changes
- changes can only be stashed at the current HEAD
- changes can only be unstashed at the current HEAD
AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08).
Data as JSON: /api/errors/55a74494acb5df31.
Report an issue: GitHub.
Appendix: source
Thrown at gix-tix/src/edit/time_travel.rs:751
clippy::too_many_arguments,
reason = "time travel context plus rebased-commit reporting"
)]
pub(crate) fn perform_reporting_rebased(
repository_path: &Path,
bare: bool,
mut selected: ObjectId,
graph: &history::HistoryGraph,
review_roots: &[ObjectId],
revisions: &[OsString],
include_worktrees: bool,
mut report: impl FnMut(ObjectId),
) -> Result<Perform> {
let mut repository =
open_repository(repository_path, bare, false).context("could not open repository for time-travel")?;
repository.workdir().context("time-travel requires a worktree")?;
let head = repository.head().context("could not read HEAD before time-travel")?;
let Some(mut head_id) = head.id().map(gix::Id::detach) else {
anyhow::bail!("cannot time-travel from an unborn HEAD");
};
let head_was_detached = head.is_detached();
drop(head);
if repository
.index_or_empty()
.context("could not inspect the index before time-travel")?
.entries()
.iter()
.any(|entry| entry.stage() != gix::index::entry::Stage::Unconflicted)
{
anyhow::bail!("cannot time-travel with unresolved index conflicts");
}
let source_review = review_tree(&repository, graph, review_roots, head_id)?;
let destination_review = review_tree(&repository, graph, review_roots, selected)?;
let crosses_review_boundary =
source_review.as_ref().map(|review| review.root) != destination_review.as_ref().map(|review| review.root);
let mut completed_graph = None;
let mut original_ids = HashMap::new();View on GitHub (pinned to e73179060b)