{"record":{"id":"0706bf090001baba","repo":"nikivdev/code","slug":"git-failed-0706bf","errorCode":null,"errorMessage":"git {} failed","messagePattern":"git (.+?) failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/ext.rs","lineNumber":405,"sourceCode":"    let output = Command::new(\"jj\")\n        .current_dir(repo_root)\n        .args(args)\n        .output()\n        .with_context(|| format!(\"failed to run jj {}\", args.join(\" \")))?;\n    if !output.status.success() {\n        bail!(\"jj {} failed\", args.join(\" \"));\n    }\n    Ok(String::from_utf8_lossy(&output.stdout).to_string())\n}\n\nfn git_capture_in(repo_root: &Path, args: &[&str]) -> Result<String> {\n    let output = Command::new(\"git\")\n        .current_dir(repo_root)\n        .args(args)\n        .output()\n        .with_context(|| format!(\"failed to run git {}\", args.join(\" \")))?;\n    if !output.status.success() {\n        bail!(\"git {} failed\", args.join(\" \"));\n    }\n    Ok(String::from_utf8_lossy(&output.stdout).to_string())\n}\n\nfn prompt_yes_no(message: &str, default_yes: bool) -> Result<bool> {\n    let prompt = if default_yes { \"[Y/n]\" } else { \"[y/N]\" };\n    print!(\"{message} {prompt}: \");\n    io::stdout().flush()?;\n    if !io::stdin().is_terminal() {\n        bail!(\"Non-interactive session; cannot confirm action.\");\n    }\n    let mut input = String::new();\n    io::stdin().read_line(&mut input)?;\n    let answer = input.trim().to_ascii_lowercase();\n    if answer.is_empty() {\n        return Ok(default_yes);\n    }\n    Ok(answer == \"y\" || answer == \"yes\")","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/ext.rs#L387-L423","documentation":"git_capture_in runs a git command in the repo root and captures stdout; a non-zero exit status produces this bail with the joined arguments. Used by prepare_source_workspace to inspect the colocated git side of the source workspace.","triggerScenarios":"git binary missing from PATH; running a git command outside a git repository (source jj repo is not colocated); invalid arguments or git hooks failing during the queried operation.","commonSituations":"Importing a jj workspace created without --colocate (no .git); minimal containers/CI images without git installed; git version too old for the flags used.","solutions":["Run the same git command manually in the source repo to see the real git error.","Ensure git is installed and on PATH (`git --version`).","If the source lacks .git, recreate the workspace with `jj git init --colocate`."],"exampleFix":"// before\nlet out = git_capture_in(&repo_root, &[\"status\", \"--porcelain\"])?;\n// after (shell diagnosis first)\n// cd <source> && git status --porcelain   # observe the actual git error\nlet out = git_capture_in(&repo_root, &[\"status\", \"--porcelain\"])?;","handlingStrategy":"validation","validationCode":"if std::process::Command::new(\"git\").arg(\"--version\").output().map(|o| !o.status.success()).unwrap_or(true) {\n    return Err(anyhow!(\"git is not installed or not functioning\"));\n}\nif !source.join(\".git\").exists() {\n    return Err(anyhow!(\"{} has no .git; recreate with `jj git init --colocate`\", source));\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = import_external_path(source) {\n    if e.to_string().starts_with(\"git \") {\n        eprintln!(\"git step failed ({e}); run the same git command in the source repo to diagnose\");\n    } else { return Err(e.into()); }\n}","preventionTips":["Install git in minimal/CI images that use this tool.","Create source workspaces with --colocate so git commands succeed.","Check git version supports the flags the tool passes."],"tags":["vcs","subprocess","git"],"backgroundTag":"external-command-failed","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}