{"record":{"id":"44eae3c4d879efef","repo":"nikivdev/code","slug":"exists-but-is-not-a-git-repo","errorCode":null,"errorMessage":"{} exists but is not a git repo: {}","messagePattern":"(.+?) exists but is not a git repo: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/home.rs","lineNumber":570,"sourceCode":"        println!(\n            \"  not linked: {} (expected -> {})\",\n            dest.display(),\n            source.display()\n        );\n    }\n\n    Ok(())\n}\n\nfn ensure_repo(\n    dest: &Path,\n    repo_url: Option<&str>,\n    label: &str,\n    allow_origin_reset: bool,\n) -> Result<()> {\n    if dest.exists() {\n        if !dest.join(\".git\").exists() {\n            bail!(\"{} exists but is not a git repo: {}\", label, dest.display());\n        }\n\n        if let Some(expected) = repo_url {\n            if allow_origin_reset {\n                ensure_origin_url(dest, expected)?;\n            } else if let Ok(actual) = git_capture(dest, &[\"remote\", \"get-url\", \"origin\"]) {\n                if !urls_match(expected, actual.trim()) {\n                    bail!(\n                        \"{} origin mismatch: expected {}, got {}\",\n                        label,\n                        expected,\n                        actual.trim()\n                    );\n                }\n            }\n        }\n\n        update_repo(dest)?;","sourceCodeStart":552,"sourceCodeEnd":588,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/home.rs#L552-L588","documentation":"ensure_repo verifies that a destination directory either doesn't exist (and will be cloned) or is a valid git checkout. If dest exists but has no .git directory, the library refuses to proceed — it will not clone into or operate on a non-repo directory, since it can't manage its origin or pull updates.","triggerScenarios":"ensure_repo (called by run or ensure_kar_repo) finds dest.exists() == true while dest.join(\".git\") is missing.","commonSituations":"A stale or partially-deleted clone left an empty/plain directory at the target path; the user created the directory manually beforehand; a previous non-git tool wrote files to that location; .git was deleted during cleanup.","solutions":["Delete the existing directory so the tool can clone fresh: rm -rf <dest>","If the content is wanted, run `git init` + `git remote add origin <url>` + fetch inside it (only if it really is the repo content)","Move the existing directory aside and re-run"],"exampleFix":"// before\n$ f home sync   # ~/.config/kar exists but no .git\n// after\n$ mv ~/.config/kar ~/.config/kar.bak\n$ f home sync   # clones repo into ~/.config/kar","handlingStrategy":"validation","validationCode":"if dest.exists() && !dest.join(\".git\").exists() {\n    eprintln!(\"{} is not a git repo; remove or move it before syncing\", dest.display());\n}","typeGuard":"fn is_git_repo(dir: &Path) -> bool {\n    dir.join(\".git\").exists()\n}","tryCatchPattern":"match ensure_repo(...) {\n    Err(e) if e.to_string().contains(\"exists but is not a git repo\") => {\n        eprintln!(\"inspect/remove {} and re-run\", dest.display());\n    }\n    r => r?,\n}","preventionTips":["Don't pre-create the destination directory; let the tool clone it","After partial deletes, remove leftovers before re-syncing","Add a pre-sync check that target paths are either absent or valid repos"],"tags":["git","repo-state","dotfiles"],"backgroundTag":"directory-not-a-git-repo","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}