Repository navigation
Register --only-uncommitted scans as partial scans - #186
Ibrahimrahhal wants to merge 1 commit into
Conversation
Pack the whole project and send the uncommitted files as files_to_scan with partial_scan=true, the way pull request scans are registered, instead of an archive of only those files that the server took for the branch's full state.
| Some("git:staged,git:modified,git:untracked") | ||
| // Only --target narrows the archive. --only-uncommitted packs the whole | ||
| // project and names its files in the upload, the way a pull request scan is | ||
| // registered: an archive of just those files reads to the server as the |
There was a problem hiding this comment.
high: --target can incorrectly narrow an --only-uncommitted scan
The previous logic gave --only-uncommitted precedence over target. The new code always assigns target_str from --target while independently resolving all uncommitted files. Packaging is therefore target-limited, and partial_scan_files later intersects the uncommitted set with that archive. An uncommitted file outside --target is skipped or can cause the command to report no scannable changes, despite the help text promising that --only-uncommitted uploads the whole project. Either make these options explicitly conflict or preserve --only-uncommitted precedence.
Proof or reproduction:
Given committed main.py and modified edited.py:
corgea scan --only-uncommitted --target main.py
The archive contains only main.py, while selected contains edited.py. Since archived.contains("edited.py") is false, partial_scan_files places it in skipped and returns an empty files list, causing the scan to exit even though edited.py is a valid uncommitted source file.
There was a problem hiding this comment.
Automated review risk: 3/5.
The new partial-scan flow is generally coherent, but combining --only-uncommitted with --target can silently narrow the archive and omit uncommitted files, contradicting the documented behavior.
Critical or high-priority changes must be addressed.
Automatic approval was not submitted: automated review found critical or high-priority findings.
There was a problem hiding this comment.
--only-uncommitted drops git changes the old packer scanned. files_to_scan is intersected with the standard-filter project walk, so hidden paths and tracked files that match .gitignore never enter the archive and are then skipped. A workflow-only edit exits 1; a mixed commit succeeds without scanning that file.
Sent by Cursor Automation: pr-flow
| let (files, skipped) = partial_scan_files( | ||
| &selected, | ||
| &roots, | ||
| &force_included, | ||
| &archive_contents.entry_names, |
There was a problem hiding this comment.
entry_names comes from create_zip_from_target with target == None, which walks with WalkBuilder::standard_filters(true) (src/utils/generic.rs:212). That walk skips hidden paths and .gitignore matches, including files that are still tracked. git:staged / git:modified still return those paths (src/targets.rs:275-280), archived.contains fails, and partial_scan_files reports them skipped.
Reproduced with the same filters: after committing and editing .github/workflows/ci.yml, a force-added ignored.py, and src/app.py, git status --porcelain lists all three. A default rg walk (same ignore crate defaults) lists only src/app.py. The new test only adds an untracked root edited.py, so it stays green.
The previous --only-uncommitted path passed git:staged,git:modified,git:untracked as the zip target, which packs those paths directly and only then applies DEFAULT_EXCLUDE_GLOBS. Both the workflow file and ignored.py were uploaded.
Impact: the pre-commit hook (setup_hooks.rs) runs corgea scan blast --only-uncommitted --fail-on LO. A commit that only changes .github/workflows/ci.yml now exits 1 with "no scannable uncommitted changes". A commit that also touches a normal source file succeeds, warns that the workflow is not source code, and omits it from files_to_scan, so --scan-type secrets never sees a secret added there.
Do not fix this by naming files that are absent from the zip; the server rejects that and fails the upload. After the walker builds files_to_zip, add resolved uncommitted files that exist on disk and are not matched by DEFAULT_EXCLUDE_GLOBS or --exclude. force_include is the wrong hook: it also bypasses those globs and would start scanning tests/**, *.css, and *.env. Cover it by extending scan_only_uncommitted_uploads_the_project_and_names_the_changed_files with a modified .github/workflows/ci.yml and a tracked gitignored file, and assert both names are in the zip and in files_to_scan.


Why
corgea scan --only-uncommitteduploaded an archive of only the changed files, with no partial-scan marker. The server registered that as the branch's latest full scan, so the project page andGET /issues?project=&branch=showed only those files' issues.Change
--only-uncommittednow packs the whole project, the same as a normal scan, and sendspartial_scan=trueplusfiles_to_scan(a JSON array of zip entry names). This is how pull request scans are registered.git:staged,git:modified,git:untracked) is resolved separately and matched against the archive's entry names (ArchiveContents.entry_names). Files that packaging leaves out, such as vendored or generated files or files outside the scanned directory, are listed as skipped instead of being sent. Sending them would fail the upload on the server. Force-included files are added to the list.dirty=true, build no file manifest and skip incremental planning, so they can never be used as a commit baseline.--include-imageand no scannable changes, the scan is still partial, withfiles_to_scan=[].--only-uncommittedand--disable-incrementalhelp text.Dependencies
Requires Corgea/doghouse#2348, which accepts a JSON
files_to_scanand registers CLI partial scans. Deploy that before releasing this change.Tests
partial_scan_files.partial_scan=true,files_to_scan=["edited.py"],dirty=true, and nofile_manifest.files_to_scan=[]../harness check: clippy, format, and 953 tests all pass.