{"record":{"id":"7357b323b26afff1","repo":"affaan-m/ECC","slug":"cannot-reset-hunks-for-untracked-files","errorCode":null,"errorMessage":"cannot reset hunks for untracked files","messagePattern":"cannot reset hunks for untracked files","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"warning","filePath":"ecc2/src/worktree/mod.rs","lineNumber":432,"sourceCode":"pub fn unstage_hunk(worktree: &WorktreeInfo, hunk: &GitPatchHunk) -> Result<()> {\n    if hunk.section != GitPatchSectionKind::Staged {\n        anyhow::bail!(\"selected hunk is not staged\");\n    }\n    git_apply_patch(\n        &worktree.path,\n        &[\"-R\", \"--cached\"],\n        &hunk.patch,\n        \"unstage selected hunk\",\n    )\n}\n\npub fn reset_hunk(\n    worktree: &WorktreeInfo,\n    entry: &GitStatusEntry,\n    hunk: &GitPatchHunk,\n) -> Result<()> {\n    if entry.untracked {\n        anyhow::bail!(\"cannot reset hunks for untracked files\");\n    }\n\n    match hunk.section {\n        GitPatchSectionKind::Unstaged => {\n            git_apply_patch(&worktree.path, &[\"-R\"], &hunk.patch, \"reset selected hunk\")\n        }\n        GitPatchSectionKind::Staged => {\n            if entry.unstaged {\n                anyhow::bail!(\n                    \"cannot reset a staged hunk while the file also has unstaged changes; unstage it first\"\n                );\n            }\n            git_apply_patch(\n                &worktree.path,\n                &[\"-R\", \"--index\"],\n                &hunk.patch,\n                \"reset selected staged hunk\",\n            )","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/ecc2/src/worktree/mod.rs#L414-L450","documentation":"reset_hunk refuses to operate when `entry.untracked == true`. Untracked files have no tracked baseline in HEAD, so the reverse-patch logic reset_hunk uses (`git apply -R` / `-R --index`) is meaningless for them. reset_path already handles untracked entries by deleting them from the filesystem; reset_hunk is the wrong entry point.","triggerScenarios":"Caller selected a hunk belonging to an untracked file (where `git_status_patch_view` returns `None`, but a stale hunk was constructed elsewhere) and passed it with the entry to reset_hunk. UI offered a per-hunk reset on an untracked row.","commonSituations":"Stale GitStatusEntry retained after the file transitioned to untracked; UI dispatch table does not distinguish untracked rows from tracked ones for the reset verb.","solutions":["Branch on `entry.untracked`: route untracked entries to reset_path (which deletes them) instead of reset_hunk.","For untracked entries, `git_status_patch_view` already returns None — derive hunks only from that view so untracked hunks never reach reset_hunk.","Hide the per-hunk reset control on untracked rows."],"exampleFix":"// before\nreset_hunk(&worktree, &entry, &hunk)?;\n\n// after\nif entry.untracked {\n    reset_path(&worktree, &entry)?; // deletes the untracked file\n} else {\n    reset_hunk(&worktree, &entry, &hunk)?;\n}","handlingStrategy":"type-guard","validationCode":"use crate::worktree::{GitStatusEntry, reset_hunk, reset_path};\n\nfn reset_entry_or_hunk(\n    worktree: &WorktreeInfo,\n    entry: &GitStatusEntry,\n    hunk: Option<&GitPatchHunk>,\n) -> anyhow::Result<()> {\n    if entry.untracked {\n        return reset_path(worktree, entry); // deletes the file\n    }\n    match hunk {\n        Some(h) => reset_hunk(worktree, entry, h),\n        None => reset_path(worktree, entry),\n    }\n}","typeGuard":"fn is_tracked(entry: &GitStatusEntry) -> bool {\n    !entry.untracked\n}","tryCatchPattern":"match reset_hunk(&worktree, &entry, &hunk) {\n    Ok(()) => { /* refresh */ }\n    Err(e) if format!(\"{e}\").contains(\"untracked files\") => {\n        reset_path(&worktree, &entry)?;\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Route untracked rows to reset_path; never construct hunks for them.","Hide per-hunk reset UI on untracked entries.","Derive hunks only from `git_status_patch_view`, which already returns None for untracked paths."],"tags":["git","worktree","state-machine","validation","untracked"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}