Skip to content

feat: add SVN (Subversion) working copy support#255

Open
xiaoye5200 wants to merge 1 commit intotirth8205:mainfrom
xiaoye5200:fix/svn
Open

feat: add SVN (Subversion) working copy support#255
xiaoye5200 wants to merge 1 commit intotirth8205:mainfrom
xiaoye5200:fix/svn

Conversation

@xiaoye5200
Copy link
Copy Markdown

Summary

Adds first-class SVN support alongside the existing Git integration,
so that projects using Subversion can build and incrementally update
the knowledge graph without any manual configuration.

What changed

incremental.py

  • find_svn_root() — walks up the directory tree to locate the SVN
    working-copy root (handles both SVN 1.6 per-directory .svn and
    the single-root layout introduced in SVN 1.7).
  • detect_vcs(root) — returns "git", "svn", or "none" based on
    VCS markers at a given path. Used internally to dispatch to the
    correct VCS backend.
  • find_repo_root() — now falls back to find_svn_root() when no
    .git directory is found.
  • get_changed_files() — for SVN repos, uses svn status (working-
    copy changes) or svn diff --summarize -r rXXX:HEAD when the base
    parameter is a valid SVN revision range.
  • get_staged_and_unstaged() — delegates to svn status for SVN repos.
  • get_all_tracked_files() — tries svn list -R for SVN repos, falls
    back to a filesystem walk (which is also the existing Git fallback).
  • _svn_revision_info() — reads branch path and revision number from
    svn info.
  • _store_vcs_metadata() — helper that writes either
    git_branch/git_head_sha or svn_branch/svn_revision metadata
    depending on the detected VCS; used in both full_build() and
    incremental_update().
  • Added .svn/** to DEFAULT_IGNORE_PATTERNS.

changes.py

  • parse_svn_diff_ranges() — runs svn diff and feeds the unified-diff
    output into the existing _parse_unified_diff() for line-level change
    mapping. Accepts an optional revision range.
  • parse_diff_ranges() — VCS-aware dispatcher: routes to the SVN or
    Git diff parser based on the presence of a .svn marker.
  • analyze_changes() now calls parse_diff_ranges() instead of
    parse_git_diff_ranges(), so line-level risk scoring works for SVN
    diffs automatically.

tools/review.pyget_review_context uses parse_diff_ranges()
instead of parse_git_diff_ranges().

tools/__init__.py — exports parse_svn_diff_ranges and
parse_diff_ranges alongside the existing parse_git_diff_ranges for
backward compatibility.

cli.py — the status command shows SVN branch and revision number
for SVN working copies instead of the Git branch/SHA block.

Backward compatibility

All existing Git behavior is unchanged. The SVN path is only activated
when a .svn directory is detected; every function still accepts the
same parameters as before.

Testing

  • Verified with a local SVN working copy (SVN 1.14, server-side).
  • All existing test_incremental.py and test_changes.py tests pass
    without modification.
  • Pre-existing Windows teardown failures (file-lock on SQLite temp
    files in teardown) are unrelated to this PR.

Notes

  • svn list -R queries the server and may be slow on large repos;
    the filesystem-walk fallback kicks in automatically if it fails or
    times out.
  • The base parameter semantics for SVN: a string matching
    r?\d+(:r?\d+|:HEAD|:BASE|:COMMITTED)? is treated as an SVN
    revision range; anything else (including the default "HEAD~1")
    is ignored and svn status is used instead.

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.

1 participant