{"record":{"id":"c7e2638afa89e0ec","repo":"plandex-ai/plandex","slug":"error-checking-for-uncommitted-changes-for-file-s","errorCode":null,"errorMessage":"error checking for uncommitted changes for file %s | err: %v, output: %s","messagePattern":"error checking for uncommitted changes for file (.+?) \\| err: (.+?), output: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/git.go","lineNumber":197,"sourceCode":"\t\treturn fmt.Errorf(\"error resetting staged changes | err: %v, output: %s\", err, string(res))\n\t}\n\n\t// Clean untracked files\n\tres, err = exec.Command(\"git\", \"clean\", \"-d\", \"-f\").CombinedOutput()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error cleaning untracked files | err: %v, output: %s\", err, string(res))\n\t}\n\n\treturn nil\n}\n\nfunc GitFileHasUncommittedChanges(path string) (bool, error) {\n\tgitMutex.Lock()\n\tdefer gitMutex.Unlock()\n\n\tres, err := exec.Command(\"git\", \"status\", \"--porcelain\", path).CombinedOutput()\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"error checking for uncommitted changes for file %s | err: %v, output: %s\", path, err, string(res))\n\t}\n\n\treturn strings.TrimSpace(string(res)) != \"\", nil\n}\n\nfunc GitCheckoutFile(path string) error {\n\tgitMutex.Lock()\n\tdefer gitMutex.Unlock()\n\n\tres, err := exec.Command(\"git\", \"checkout\", path).CombinedOutput()\n\tif err != nil {\n\t\tlog.Println(\"Error checking out file:\", string(res))\n\n\t\treturn fmt.Errorf(\"error checking out file %s | err: %v, output: %s\", path, err, string(res))\n\t}\n\n\treturn nil\n}","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/git.go#L179-L215","documentation":"GitFileHasUncommittedChanges runs `git status --porcelain <path>` and reports true if the output is non-empty. This error is returned only when the git command itself fails (non-zero exit), with the command output embedded. An empty or dirty file is a normal result, not an error.","triggerScenarios":"Calling GitFileHasUncommittedChanges(path) when `git status --porcelain path` fails: git not installed/on PATH, path is outside any git repository, or git cannot resolve the pathspec.","commonSituations":"Invoking the check in a directory that is not a git checkout, checking a file that was never tracked inside a repo without a .git dir, missing git binary in a minimal container image.","solutions":["Run `git rev-parse --show-toplevel` in the same cwd to confirm you are inside a repository.","Check `which git` and install the git binary if it is missing.","Inspect the `output:` field in the error for git's specific complaint (bad path, not a repo, etc.).","Ensure the path passed is relative to the repo root or absolute but inside the repo."],"exampleFix":"// before\nok, err := GitFileHasUncommittedChanges(path)\n// after\nif _, err := os.Stat(filepath.Join(dir, \".git\")); err != nil {\n    return fmt.Errorf(\"%s is not inside a git repository\", dir)\n}\nok, err := GitFileHasUncommittedChanges(path)","handlingStrategy":"validation","validationCode":"func inGitRepo(dir string) bool {\n    out, err := exec.Command(\"git\", \"-C\", dir, \"rev-parse\", \"--is-inside-work-tree\").Output()\n    return err == nil && strings.TrimSpace(string(out)) == \"true\"\n}","typeGuard":null,"tryCatchPattern":"dirty, err := GitFileHasUncommittedChanges(path)\nif err != nil {\n    if strings.Contains(err.Error(), \"not a git repository\") {\n        return false, nil // treat as no changes outside a repo\n    }\n    return err\n}","preventionTips":["Verify cwd is a git repo before status checks","Pass repo-relative paths","Install git in minimal/container images","Pre-check with `git ls-files <path>`"],"tags":["git","cli","subprocess"],"backgroundTag":"git-command-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}