{"record":{"id":"cacde4d9fd144a01","repo":"nikivdev/code","slug":"refusing-to-bootstrap-dirty-repo-during-clone-b","errorCode":null,"errorMessage":"refusing to bootstrap dirty repo {} during clone bootstrap","messagePattern":"refusing to bootstrap dirty repo (.+?) during clone bootstrap","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/repos.rs","lineNumber":816,"sourceCode":"    let mut status = repo_home_branch_status_with_options(\n        repo_root,\n        &options.home_branch,\n        options.ensure_private_mirror,\n    )?;\n\n    if !status.eligible {\n        let result = HomeBranchBootstrapResult {\n            repo_root: repo_root.display().to_string(),\n            changed: false,\n            switched_to_home_branch: false,\n            status,\n            steps: vec![\"skipped: repo is not a supported GitHub checkout\".to_string()],\n        };\n        return Ok(result);\n    }\n\n    if options.fail_on_dirty && status.working_tree_dirty {\n        bail!(\n            \"refusing to bootstrap dirty repo {} during clone bootstrap\",\n            repo_root.display()\n        );\n    }\n\n    let public_remote = status\n        .public_remote\n        .clone()\n        .ok_or_else(|| anyhow::anyhow!(\"missing public remote for {}\", repo_root.display()))?;\n    let public_default_branch = status.public_default_branch.clone().ok_or_else(|| {\n        anyhow::anyhow!(\"missing public default branch for {}\", repo_root.display())\n    })?;\n    let home_branch = status.home_branch.clone();\n\n    if status.configured_home_branch.as_deref() != Some(home_branch.as_str()) {\n        steps.push(format!(\"set git config flow.homeBranch={home_branch}\"));\n        if !options.dry_run {\n            git_run_in(","sourceCodeStart":798,"sourceCodeEnd":834,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/repos.rs#L798-L834","documentation":"During clone bootstrap, if the cloned repo's working tree is dirty and options.fail_on_dirty is set, bootstrap refuses to proceed rather than operating on uncommitted changes. This protects against stashing/committing/resetting user changes implicitly.","triggerScenarios":"bootstrap_clone_repo invoked on a repo whose git status shows a dirty working tree, with fail_on_dirty enabled.","commonSituations":"Post-clone hooks or editors created/modified files before bootstrap ran; the user resumed work in a partially-bootstrapped repo; OS junk files (.DS_Store) make the tree dirty.","solutions":["Commit or stash the local changes, then re-run bootstrap.","Clean untracked junk files (`git clean` after review) so the tree is clean.","Re-clone into a fresh directory if changes are disposable."],"exampleFix":"// before: dirty tree, fail_on_dirty=true\nbootstrap(repo)\n// after\n$ git -C repo stash   # or commit\nbootstrap(repo)","handlingStrategy":"validation","validationCode":"fn dirty(repo: &Path) -> bool {\n    let out = std::process::Command::new(\"git\")\n        .args([\"status\", \"--porcelain\"])\n        .current_dir(repo)\n        .output()\n        .expect(\"git status\");\n    !out.stdout.is_empty()\n}\n// run bootstrap only if !dirty(repo_root) with fail_on_dirty set","typeGuard":null,"tryCatchPattern":"match bootstrap_clone_repo(&repo_root, &options) {\n    Err(e) if e.to_string().contains(\"refusing to bootstrap dirty repo\") => {\n        git(&repo_root, &[\"stash\"])?;\n        bootstrap_clone_repo(&repo_root, &options)?;\n    }\n    r => r?,\n}","preventionTips":["Commit or stash local changes before running bootstrap.","Add common junk files (.DS_Store, editor artifacts) to .gitignore.","Run bootstrap immediately after clone, before making edits.","Check `git status --porcelain` in CI before bootstrap steps."],"tags":["git","dirty-worktree","bootstrap"],"backgroundTag":"dirty-working-tree","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}