Skip to content

Fix sourcehunt preprocessor losing cloned tree to GC - #134

Merged
whatever merged 6 commits into
mainfrom
fix/sourcehunt-cloner-gc
Aug 6, 2026
Merged

Fix sourcehunt preprocessor losing cloned tree to GC#134
whatever merged 6 commits into
mainfrom
fix/sourcehunt-cloner-gc

Conversation

@whatever

@whatever whatever commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bug fix: Preprocessor._clone_or_use_local stashed the cloner SourceAnalyzer on self._analyzer, which Preprocessor.run() then rebinds to a fresh analyzer. The old cloner refcount hit zero, its tempfile.TemporaryDirectory finalizer ran, and the freshly cloned tree was rmtree'd before the file walk hit it — so any git-URL sourcehunt target produced zero file_targets. Fix binds the cloner to self._cloner so its lifetime tracks the Preprocessor.
  • Feature: SourceAnalyzer.clone() accepts a full 40-char commit SHA in branch (cwpro bridge sends these). git clone --depth 1 --branch <ref> rejects SHAs, so a SHA branch triggers a blobless full clone + git checkout <sha>; names keep the fast shallow-clone path.
  • Chore: Print the raw machine-fd sourcehunt request on stderr (routing redacted — it holds the provider key) so bridge misconfigurations surface in kubectl logs.

Test plan

  • python -m pytest tests/test_sourcehunt_preprocessor.py::TestPreprocessorClonePath -vtest_clone_survives_analyzer_rebind walks a real local git repo through the git-URL code path and asserts file_targets is populated.
  • Rerun the cwpro-bridge sourcehunt request that just came in against gitea @ f6e2ca4388a531c4a5996fc8043c38f1cf57897f and confirm the vulnerable-commit tree is scanned.

Preprocessor._clone_or_use_local stashed the cloner SourceAnalyzer on
self._analyzer, which Preprocessor.run() then rebinds to a fresh
analyzer configured for the target repo. That dropped the only strong
reference to the cloner, so its tempfile.TemporaryDirectory finalizer
ran and rmtree'd the freshly cloned tree before the file walk hit it —
producing zero file_targets for any git-URL target.

Store the cloner on self._cloner so its lifetime is bound to the
Preprocessor. Regression test walks a real local git repo through the
git-URL code path and asserts file_targets is populated.

Also in this change:
- SourceAnalyzer.clone() accepts a full 40-char commit SHA in `branch`.
  Shallow `git clone --depth 1 --branch <ref>` rejects SHAs, so SHA
  refs fall through to a blobless full clone + `git checkout <sha>`.
- Log the raw machine-fd sourcehunt request payload (routing redacted)
  so bridge-side misconfigurations surface in kubectl logs.
Sourcehunt only ever passes branch names (CLI --branch, TargetConfig, CampaignTargetConfig all default to 'main'; the one eval that pins to a commit does its own clone + checkout and hands sourcehunt --local-path, bypassing this method). The SHA-detection code path had no caller.
Full 40-char SHAs are now valid --branch values on sourcehunt requests (cwpro bridge sends them). git clone --depth 1 --branch <ref> rejects SHAs, so a SHA branch triggers a blobless full clone followed by git checkout <sha>. Names keep the fast shallow-clone path.
@whatever
whatever merged commit d037649 into main Aug 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants