GTST-18 fix: handle untracked files in gitsift stage#15
Conversation
- Scan diff for untracked files before staging - Untracked file hunks staged via index.add_path() directly - Tracked file hunks staged via repo.apply() as before - Remaining untracked files added to index before apply() to prevent "index does not contain" failures - 2 new tests: stage with untracked present, stage untracked directly
Review -- Claude Opus 4.6Review ResultOverall Verdict: HAS_ISSUES 1. CorrectnessVerdict: HAS_ISSUES IssuesCritical
Important
Minor
Fix InstructionsCritical fix -- The "add remaining untracked to index" step at lines 303-312 must not stage files the user didn't request. Instead of adding ALL untracked files, it should add only the untracked files whose content is needed to make Important fix (staged count) -- Replace the let mut untracked_hunk_count = 0;
// In the Some((path, true)) branch:
untracked_hunk_count += 1;
// ...
staged += untracked_hunk_count; // instead of staged += untracked_stagedImportant fix (line-level untracked) -- Add a check at the start of the line-level loop: if Test fix -- Add an assertion to let index = repo.index().unwrap();
assert!(index.get_path(Path::new("new_file.txt"), 0).is_none(),
"untracked file should NOT be staged as side effect");2. ArchitectureVerdict: PASS The design is sound. Separating One minor observation: there is now significant duplication of the "iterate diff, extract path, compute hunk ID" pattern across 3. SecurityVerdict: PASS No security issues. File paths come from git2's diff output (the repository's own state). 4. PerformanceVerdict: PASS Minor observations
5. SimplicityVerdict: PASS The approach is straightforward: scan once to classify, then branch. The new functions are focused and well-named. The code reads clearly. Minor note: the SummaryThis PR correctly identifies the root cause (libgit2's |
- Remove silent staging of all untracked files when only tracked hunks requested (was corrupting staging area) - Count untracked hunks instead of file paths for staged count - Reject line-level staging for untracked files with clear error message - Add assertion that untracked file is NOT in index after tracked-only staging
Cover the case where both tracked and untracked hunk IDs are in the same request — verifies both are staged correctly.
Summary
Fix:
gitsift stagenow handles untracked/new files correctly instead of failing with "index does not contain".Problem
Previously, if the working tree contained any untracked files,
gitsift stagewould fail for ALL hunks — even hunks belonging to tracked files. The error was:Fix
scan_hunk_metadata()— identifies which hunks belong to untracked vs tracked filesindex.add_path()directly (bypassesapply())apply()to prevent failuresrepo.apply()as beforeTests (2 new, 81 total)
stage_with_untracked_files_present— staging tracked hunks works when untracked files existstage_untracked_file_hunk_directly— staging an untracked file's hunk works and file content is correct in indexManually verified