{"record":{"id":"e4116d78bcf61433","repo":"alibaba/open-code-review","slug":"git-ls-files-untracked-w","errorCode":null,"errorMessage":"git ls-files (untracked): %w","messagePattern":"git ls-files \\(untracked\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/scan/provider.go","lineNumber":174,"sourceCode":"\t\treturn p.listFilesViaGit(ctx)\n\t}\n\treturn p.listFilesViaWalk(ctx)\n}\n\n// isGitRepo reports whether p.repoDir is inside a git working tree.\nfunc (p *Provider) isGitRepo(ctx context.Context) bool {\n\tcmd := exec.CommandContext(ctx, \"git\", \"-C\", p.repoDir, \"rev-parse\", \"--git-dir\")\n\treturn cmd.Run() == nil\n}\n\nfunc (p *Provider) listFilesViaGit(ctx context.Context) ([]string, error) {\n\ttracked, err := p.gitLs(ctx, \"-z\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"git ls-files (tracked): %w\", err)\n\t}\n\tuntracked, err := p.gitLs(ctx, \"-z\", \"--others\", \"--exclude-standard\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"git ls-files (untracked): %w\", err)\n\t}\n\n\tseen := make(map[string]struct{}, len(tracked)+len(untracked))\n\tall := make([]string, 0, len(tracked)+len(untracked))\n\tfor _, f := range append(tracked, untracked...) {\n\t\tif f == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tif _, ok := seen[f]; ok {\n\t\t\tcontinue\n\t\t}\n\t\tseen[f] = struct{}{}\n\t\tall = append(all, f)\n\t}\n\treturn all, nil\n}\n\n// listFilesViaWalk recursively walks p.repoDir collecting regular files.","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/alibaba/open-code-review/blob/5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f/internal/scan/provider.go#L156-L192","documentation":"The second git call in listFilesViaGit lists untracked-but-not-ignored files via `git ls-files -z --others --exclude-standard`. A failure here is wrapped as 'git ls-files (untracked): ...'. Tracked enumeration already succeeded, so the repo is basically healthy but the --others query failed.","triggerScenarios":"p.gitLs(ctx, \"-z\", \"--others\", \"--exclude-standard\") returns an error after the tracked listing succeeded — typically context cancellation between the two calls, or an unusable temp/config state for git.","commonSituations":"Context deadline hit between the two git invocations on large repos; global gitignore or config unreadable (permissions, HOME changed); concurrent git index.lock contention.","solutions":["Run `git ls-files --others --exclude-standard` manually to reproduce the git error.","Clear a stale .git/index.lock if present.","Ensure global git config and core.excludesFile are readable.","Increase timeout / retry if the context was canceled mid-run."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"cmd := exec.Command(\"git\", \"-C\", repoDir, \"ls-files\", \"--others\", \"--exclude-standard\")\nif err := cmd.Run(); err != nil {\n    return fmt.Errorf(\"untracked listing will fail: %w\", err)\n}","typeGuard":"func isGitLsUntrackedError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"git ls-files (untracked)\")\n}","tryCatchPattern":"files, err := provider.Enumerate(ctx)\nif err != nil {\n    if strings.Contains(err.Error(), \"untracked\") {\n        // tracked listing worked; safe to retry with backoff\n        time.Sleep(time.Second)\n        return provider.Enumerate(ctx)\n    }\n    return err\n}","preventionTips":["Remove stale .git/index.lock files before automated runs.","Keep global git config (core.excludesFile) readable by the running user.","Avoid tight context deadlines between the two git invocations.","Run scans as a user with read access to the whole .git directory."],"tags":["git","file-enumeration","subprocess"],"backgroundTag":"git-command-failed","analyzedSha":"5cf97d0d15cbd41b602513c4be3bfec3cee5bf7f","analyzedAt":"2026-09-02T02:08:09.116Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}