feat: working clean/smudge round-trip for a Rust subset#26
Draft
bdelanghe wants to merge 3 commits into
Draft
Conversation
Turn the filter skeleton into a real, git-invoked AST round-trip: - printer: parse Rust with Tree-sitter and re-emit canonical source by walking the tree. Fail-closed — syntax errors and unsupported node kinds error rather than silently corrupting code. - pktline: implement Git's long-running filter pkt-line codec. - filters: speak the real `filter-process` protocol; `clean` canonicalizes `*.rs`, `smudge` is identity, non-Rust passes through. - setup: `git-ast setup` registers the filter + .gitattributes in a repo. - examples/demo.sh: end-to-end proof that reformatting produces no diff while a real change shows a clean one. Scope stays honest: one language, a documented subset, fail-closed. Diff/merge drivers remain placeholders pending stable node identity, which this does not address. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NCp6PSoWKvsbFWyav6CeeC
…sport) Add a README section framing the hard, deferred problem precisely: node identity is heuristic not exact, computed by tree-matching rather than stored, helped by content-addressed subtree hashing, and git notes are a transport for attribution across rewrites — not the identity mechanism. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NCp6PSoWKvsbFWyav6CeeC
frond exercises the same parse -> regenerate -> compare primitive for JavaScript/TypeScript (SWC on Deno) that git-ast does for Rust (Tree-sitter). Cross-link them: frond validates round-trip fidelity, the prerequisite git-ast's canonical printer depends on. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NCp6PSoWKvsbFWyav6CeeC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Turns the filter skeleton into a real, git-invoked AST round-trip. With the filter installed,
git addstores Rust in canonical form andgit checkoutreturns it — so reformatting never enters history.Before this PR the filter was a no-op that didn't even speak git's protocol; the only "round-trip" was a string-prefix marker in a unit test.
Changes
printer.rs— the AST-native core. Parses Rust with Tree-sitter and re-emits canonical source by walking the tree. Fail-closed: syntax errors reject the commit; any unsupported node kind returns an error rather than silently corrupting code.pktline.rs— codec for git's long-running filter pkt-line framing.filters.rs— implements the realfilter-processprotocol (handshake → capabilities → per-blob).cleancanonicalizes*.rs,smudgeis identity, non-Rust passes through.setup.rs/git-ast setup— one command to register the filter +.gitattributesin a repo (idempotent).examples/demo.sh— end-to-end proof: a pure reformat produces no diff, a reala + b→a - bchange shows a clean one-line diff.Verified
18 tests pass;
cargo fmt --checkandcargo clippy --all-targets -- -D warningsare clean. Demonstrated through realgit add/git checkout/git diffin a throwaway repo (seeexamples/demo.sh).Scope — deliberately honest
let, binary/call/macro expressions, literals, comments). Widening coverage is additive — one arm per node kind.docs/planning/scope.md.🤖 Generated with Claude Code
Generated by Claude Code