GitoxideLabs/gitoxide · error

{notice}

Error message

{notice}

What it means

After a time-travel conflict was materialized (per --materialize-conflicts), tix records undo state and ref rewrites, prints the conflict notice, and exits with an error to signal that the checkout did not complete. The notice text (e.g. which files conflict) comes from conflict.accept() and is re-raised verbatim.

Solutions

  1. Read the printed notice to see which paths conflict and resolve the markers
  2. Continue or abort the time-travel per the notice/undo instructions
  3. In scripts, detect this specific bail as 'conflict materialized, awaiting resolution' rather than a crash

Example fix

// before
tix travel $dest --materialize-conflicts || exit 1
// after
tix travel "$dest" --materialize-conflicts || { grep -q 'CONFLICT' <(tix travel "$dest" --materialize-conflicts 2>&1) && resolve_and_continue; }
Defensive patterns

Strategy: try-catch

Try / catch

let out = Command::new("tix").args(["travel", dest, "--materialize-conflicts"]).output()?;
if !out.status.success() && String::from_utf8_lossy(&out.stderr).contains("CONFLICT") {
    // materialized: resolve markers, then follow the printed continue instruction
}

Prevention

When it happens

Trigger: `tix travel <dest> --materialize-conflicts` where the underlying Perform result is Perform::Conflict; tix materializes markers, prints ref rewrites/undo, then bails with the notice string.

Common situations: Travelling to a commit whose tree conflicts with local/index state; materializing conflicts to inspect them before continuing; automation treating the non-zero exit as a hard failure.

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


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/28ce901570ac5b01. Report an issue: GitHub.

Appendix: source

Thrown at gix-tix/src/command/travel.rs:124

                .context("could not reopen repository after time-travel")?;
            println!(
                "{}",
                super::notice_with_change_id(
                    &repository,
                    &notice.unwrap_or_else(|| format!("already at {}", selected.to_hex_with_len(7))),
                    selected,
                )?
            );
            super::print_ref_rewrites(&repository, &ref_rewrites)?;
            super::record_undo(&repository, "time travel", Ok(ref_changes));
        }
        crate::edit::time_travel::Perform::Conflict(conflict) if args.materialize_conflicts => {
            let (notice, _, ref_rewrites, ref_changes) = conflict.accept()?;
            let repository = crate::open_repository(&repository_path, bare, false)
                .context("could not reopen repository after materializing time-travel")?;
            super::print_ref_rewrites(&repository, &ref_rewrites)?;
            super::record_undo(&repository, "materialize time-travel conflict", Ok(ref_changes));
            anyhow::bail!("{notice}");
        }
        crate::edit::time_travel::Perform::Conflict(_) => {
            anyhow::bail!("time-travel would conflict; retry with --materialize-conflicts to check it out")
        }
    }
    Ok(())
}

fn relative_destination(
    repository: &gix::Repository,
    graph: &crate::history::HistoryGraph,
    hidden_tips: &[gix::ObjectId],
    head: gix::ObjectId,
    to: To,
) -> Result<gix::ObjectId> {
    let order = graph
        .stored_commit_ids()
        .filter(|id| !hidden_tips.iter().any(|hidden| graph.is_ancestor(*id, *hidden)))

View on GitHub (pinned to e73179060b)