nikivdev/code · warning

Aborted; commit or stash changes before continuing.

Error message

Aborted; commit or stash changes before continuing.

What it means

When the source workspace has uncommitted/dirty state, prepare_source_workspace asks the user to confirm continuing. Answering no (the default) aborts the import, telling the user to commit or stash first so the imported snapshot is consistent.

Source

Thrown at src/ext.rs:267

    };

    let workspace = workspace_name_for_project(project_root)?;
    if workspace.is_empty() {
        return Ok(source.to_path_buf());
    }

    let status = git_capture_in(&repo_root, &["status", "--porcelain"]).unwrap_or_default();
    if !status.trim().is_empty() {
        println!("Source repo has uncommitted changes:");
        for line in status.lines().take(20) {
            println!("  {line}");
        }
        let continue_anyway = prompt_yes_no(
            &format!("Continue and use jj workspace \"{}\"?", workspace),
            false,
        )?;
        if !continue_anyway {
            bail!("Aborted; commit or stash changes before continuing.");
        }
    }

    let workspaces = jj_workspace_list(&repo_root).unwrap_or_default();
    if let Some(existing_path) = workspaces.get(&workspace) {
        return Ok(PathBuf::from(existing_path));
    }

    let base = workspace_base(&repo_root)?;
    fs::create_dir_all(&base).with_context(|| format!("failed to create {}", base.display()))?;
    let workspace_path = base.join(&workspace);
    jj_run_in(
        &repo_root,
        &[
            "workspace",
            "add",
            workspace_path
                .to_str()

View on GitHub (pinned to a747e741ae)

Solutions

  1. In the source workspace run `jj commit` (or `jj new`) to describe the working copy, then retry.
  2. Use `jj st` to review changes and `jj restore`/stash anything unwanted.
  3. If the state is intentional, answer 'y' at the confirmation prompt.

Example fix

// before (shell)
import-external ~/repos/dirty-ws   # answer: n
// after (shell)
cd ~/repos/dirty-ws && jj commit -m "wip before import"
import-external ~/repos/dirty-ws
Defensive patterns

Strategy: validation

Validate before calling

let st = std::process::Command::new("jj")
    .args(["st"])
    .current_dir(source)
    .output()?;
let dirty = String::from_utf8_lossy(&st.stdout).contains("Working copy changes");
if dirty {
    return Err(anyhow!("Commit or stash changes in {} before importing", source));
}
import_external_path(source)?;

Type guard

fn has_uncommitted_changes(status_output: &str) -> bool {
    !status_output.trim().is_empty()
}

Try / catch

match import_external_path(source) {
    Err(e) if e.to_string().contains("Aborted") => {
        eprintln!("Clean the source workspace (jj commit / jj new) and retry");
    }
    other => other?,
}

Prevention

When it happens

Trigger: import_external_path on a jj workspace with working-copy changes, and the user presses Enter or answers 'n' at the "Continue and use jj workspace ...?" prompt (default_yes=false).

Common situations: Importing a workspace mid-development with uncommitted edits; accidentally accepting the safe default; scripted runs where stdin yields a non-affirmative answer.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/13e111f6a1c44bac. Report an issue: GitHub.