{"record":{"id":"b89f7b206faf4f18","repo":"GitoxideLabs/gitoxide","slug":"cannot-time-travel-with-unresolved-index-conflicts","errorCode":null,"errorMessage":"cannot time-travel with unresolved index conflicts","messagePattern":"cannot time-travel with unresolved index conflicts","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-tix/src/edit/time_travel.rs","lineNumber":762,"sourceCode":"    mut report: impl FnMut(ObjectId),\n) -> Result<Perform> {\n    let mut repository =\n        open_repository(repository_path, bare, false).context(\"could not open repository for time-travel\")?;\n    repository.workdir().context(\"time-travel requires a worktree\")?;\n    let head = repository.head().context(\"could not read HEAD before time-travel\")?;\n    let Some(mut head_id) = head.id().map(gix::Id::detach) else {\n        anyhow::bail!(\"cannot time-travel from an unborn HEAD\");\n    };\n    let head_was_detached = head.is_detached();\n    drop(head);\n    if repository\n        .index_or_empty()\n        .context(\"could not inspect the index before time-travel\")?\n        .entries()\n        .iter()\n        .any(|entry| entry.stage() != gix::index::entry::Stage::Unconflicted)\n    {\n        anyhow::bail!(\"cannot time-travel with unresolved index conflicts\");\n    }\n    let source_review = review_tree(&repository, graph, review_roots, head_id)?;\n    let destination_review = review_tree(&repository, graph, review_roots, selected)?;\n    let crosses_review_boundary =\n        source_review.as_ref().map(|review| review.root) != destination_review.as_ref().map(|review| review.root);\n    let mut completed_graph = None;\n    let mut original_ids = HashMap::new();\n    let mut ref_rewrites = Vec::new();\n    let mut ref_changes = Vec::new();\n    let mut pending = pending_base(&repository, selected)?;\n    while let Some(base) = pending {\n        let graph = completed_graph.as_ref().unwrap_or(graph);\n        let mut rebased = Vec::new();\n        let outcome = super::rebase::perform_reporting_rebased(\n            &repository,\n            graph,\n            super::rebase::Edit::Repeat {\n                base,","sourceCodeStart":744,"sourceCodeEnd":780,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-tix/src/edit/time_travel.rs#L744-L780","documentation":"`perform_reporting_rebased` refuses to start a time-travel operation while the repository index contains entries that are not unconflicted (i.e. an unresolved merge conflict is staged or present in the index). Before moving HEAD or materializing a different review state, the index must be clean of conflict stages, otherwise the conflict state could be silently lost or mangled. It is a guard ensuring time-travel only happens from a coherent index state.","triggerScenarios":"Calling tix time-travel (via `perform` or related entry points) while the index has entries whose stage is not `gix::index::entry::Stage::Unconflicted`, i.e. after a merge/rebase/cherry-pick conflict was resolved in the worktree but never `git add`ed, or not resolved at all.","commonSituations":"A user starts a tix time-travel right after a conflicted merge; an automated tool aborts mid-resolution leaving stage entries; a CI environment inherits a dirty repo with leftover conflict stages.","solutions":["Resolve the conflicted files and stage them (`git add <files>`) so the index only holds unconflicted stage-0 entries, then retry.","Abort the in-progress merge/rebase with `git merge --abort` or `git rebase --abort` to clear conflict stages.","Inspect the index with `git ls-files -u` to list unmerged entries before re-running the operation.","Commit or stash the current conflict resolution before invoking time-travel."],"exampleFix":"// before (conflicted index)\n// conflict markers still in file.rs, not staged\nif repo.time_travel(target).is_err() { /* cannot time-travel with unresolved index conflicts */ }\n\n// after\n// resolve file.rs, then:\nrepo.git(&[\"add\", \"file.rs\"]).expect(\"stage resolution\");\nrepo.time_travel(target).expect(\"index is conflict-free\");","handlingStrategy":"validation","validationCode":"let has_conflicts = repo.index_or_empty()?.entries().iter()\n    .any(|e| e.stage() != gix::index::entry::Stage::Unconflicted);\nif has_conflicts {\n    anyhow::bail!(\"resolve index conflicts before time-travel\");\n}","typeGuard":null,"tryCatchPattern":"match perform_reporting_rebased(&mut repo, target) {\n    Ok(report) => /* proceed */,\n    Err(e) if e.to_string().contains(\"unresolved index conflicts\") => {\n        // prompt user to resolve + `git add` before retrying\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Run `git ls-files -u` (empty output expected) before any tix time-travel","Automate conflict resolution + staging before invoking time-travel","Abort lingering merge/rebase states in CI before running tix commands"],"tags":["git","index","merge-conflict","precondition"],"backgroundTag":"invalid-state-transition","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}