Commit Graph
3 Commits
Author SHA1 Message Date
Max HsuandGitHub cc9ce09256 fix(extraction): detect untracked files inside untracked directories (#1213) (#1215)
git status --porcelain collapses an entirely-untracked directory into a
single '?? dir/' entry. collectGitStatus only recurses into such dirs to
find embedded git repos, so source files in a plain untracked directory
were never surfaced to sync — 'codegraph sync' reported 'Already up to
date' and the watcher missed them too.

Add -uall so git lists individual untracked files. Nested untracked git
repos still collapse to '?? repo/' even with -uall (git never crosses a
repo boundary), so the embedded-repo recursion is unaffected.

Export getGitChangedFiles and add regression tests for both the plain
untracked-directory case and the embedded-repo recursion (no -uall
regression).

Root-cause analysis and fix suggested by the reporter in #1213.
2026-08-22 11:53:33 -05:00
Max HsuandGitHub 340d4b033e fix(swift): remove catastrophic backtracking in Vapor route regex (#1547)
The arg-list group `(?:[^,()]+,\s*)*` was ambiguous: the trailing `\s*`
and the next iteration's `[^,()]+` could both claim the same run of
spaces, so a `.METHOD(...)` call with many comma-separated args that
never reaches `use:` forced an exponential search. Measured on
`app.get(arg0: value0, ...)`: 40ms at 20 args, 647ms at 24, 41.7s at 30,
and no result after 120s at 60.

Anchoring each repetition at a comma (`(?:[^,()]+,)*\s*`) makes the split
unique — `,` is outside the char class, so there is nothing to
re-partition. Same input is now 0.09ms at 1000 args.

Match behaviour is unchanged: all four capture groups are identical on 18
hand-written Vapor route shapes (no args, single/multi path segments,
`X.parameter`, multi-line calls, Environment.get non-matches) and on
200k fuzzed inputs.

Fixes #1544
2026-08-22 11:53:26 -05:00
6e2a24d96a fix(extraction): map PHP include/require to file→file dependency edges (#660) (#663)
PHP's importTypes only captured namespace_use_declaration, so
include/require(_once) — the dependency mechanism in procedural and
script-style PHP — never produced edges. callers, impact, and trace
missed the entire file-include graph; only namespace `use` became a
dependency edge.

Capture the four include/require expression types and emit file→file
imports edges, reusing the path-based resolution that C/C++ #include
already goes through. Only static string-literal paths are resolved
(relative to the including file); dynamic forms (include $var,
require __DIR__ . '/x', interpolated strings) are skipped.

Include PATHS are distinguished from namespace `use` symbols by shape: a
path contains '/' or '.', which PHP identifiers and FQNs never do. A
path-shaped include that doesn't resolve to a known project file is left
unresolved and does NOT fall back to the symbol name-matcher, which would
otherwise mis-connect "inc/db.php" to an unrelated db.php elsewhere — a
wrong edge is worse than a missing one.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Colby McHenry <me@colbymchenry.com>
2026-06-08 20:31:15 -04:00