Skip to content

fix: harden diff ref parsing in git worktree flow#46

Closed
bhattaraiprayag wants to merge 2 commits intoharshkedia177:mainfrom
bhattaraiprayag:fix/git-ref-injection
Closed

fix: harden diff ref parsing in git worktree flow#46
bhattaraiprayag wants to merge 2 commits intoharshkedia177:mainfrom
bhattaraiprayag:fix/git-ref-injection

Conversation

@bhattaraiprayag
Copy link
Copy Markdown

@bhattaraiprayag bhattaraiprayag commented Mar 1, 2026

Scope

This PR contains one focused bug fix for branch-diff ref handling, plus regression tests for that same behavior.

Why

axon diff passed user-provided refs directly to git worktree add, so refs starting with - could be parsed as git options.

What changed

  • Added _validate_ref(repo_path, ref) in src/axon/core/diff.py:
    • rejects refs that start with -
    • validates refs with git rev-parse --verify --quiet --end-of-options <ref>^{commit}
  • diff_branches() now validates base_ref and optional current_ref before graph build/worktree operations.
  • _build_graph_for_ref() now calls:
    • git worktree add <path> -- <ref>
      so user refs are always passed after end-of-options.
  • Added regression tests in tests/core/test_diff.py for:
    • accepted refs (main, feature/x, HEAD~1)
    • rejected dash-prefixed refs
    • rejected literal $(id) refs (treated as plain ref text)
    • pre-build validation in diff_branches
    • -- separator presence in worktree command args

Validation

  • uv run pytest -q tests/core/test_diff.py -> 23 passed
  • uv run pytest -q -> 591 passed
  • uv run ruff check src/axon/core/diff.py tests/core/test_diff.py -> pass
  • uv run ruff format --check src/axon/core/diff.py tests/core/test_diff.py -> pass
  • Runtime behavior checks:
    • axon diff -- '--detach' -> rejected
    • axon diff -- '$(id)' -> rejected as invalid ref
    • axon diff 'HEAD~1..HEAD' -> succeeds for valid refs

Closes #35
Closes #38

Checklist

  • This PR is linked to a maintainer-approved issue (or is a trivial typo/link fix under 5 lines)
  • I have read CONTRIBUTING.md
  • One logical change only — no bundled/unrelated work
  • Tests added or updated for this change
  • pytest passes locally
  • ruff check src/ tests/ passes
  • I can explain every line of this PR when asked
  • No generated project-config files (CLAUDE.md, .cursorrules, etc.)

- Reject refs that begin with '-' and verify refs with git rev-parse before running structural diff worktree operations. Pass refs to git worktree add after '--' so user-supplied refs cannot be parsed as git command options.

- Add regression coverage for dash-prefixed refs, literal $(...) refs, and command argument construction with end-of-options separation.
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.

fix: git ref injection in diff_branches via subprocess git ref starting with dash gets interpreted as option in diff_branches

1 participant