3-Way AST Merge Driver
symtrace merge-driver integrates directly into Git as a native 3-way AST semantic merge driver. Standard line-based git merge often flags false-positive conflicts when one branch re-formats code, reorders functions, or moves structs while another branch adds logic inside them. symtrace merge-driver parses the Concrete Syntax Trees of Base (%O), Ours (%A), and Theirs (%B) to resolve non-conflicting structural changes automatically with zero merge conflict markers and validates syntax integrity via AST scope splicing and re-parsing.
Quick Setup
Section titled “Quick Setup”Configure symtrace as your global or repository-specific Git merge driver:
1. Register Driver in Git Config
Section titled “1. Register Driver in Git Config”# Register symtrace merge driver commandgit config merge.symtrace.name "symtrace 3-way AST semantic merge driver"git config merge.symtrace.driver "symtrace merge-driver %O %A %B %P"2. Enable Driver in .gitattributes
Section titled “2. Enable Driver in .gitattributes”Add file associations to your repository’s .gitattributes:
*.rs merge=symtrace*.js merge=symtrace*.ts merge=symtrace*.tsx merge=symtrace*.py merge=symtrace*.java merge=symtrace*.cs merge=symtrace*.go merge=symtrace*.c merge=symtrace*.cpp merge=symtrace*.rb merge=symtrace*.php merge=symtrace*.json merge=symtraceHow 3-Way AST Resolution Works
Section titled “How 3-Way AST Resolution Works”When a Git conflict occurs during git merge or git rebase, Git executes symtrace merge-driver passing four arguments:
%O- Ancestor/Base blob temporary file path%A- Current branch (“Ours”) temporary file path%B- Incoming branch (“Theirs”) temporary file path%P- Target relative file path in the repository
Base AST (%O) / \ / \ Ours AST (%A) Theirs AST (%B) [Reformatted] [Added Function Logic] \ / \ / 3-Way AST Merge Engine │ ▼ AST Scope Splicing │ ▼ Tree-sitter Validation Re-parse (has_ast_errors()) │ ▼ Merged Clean File (%A) (Zero Conflict Markers!)1. Automatic Scope Splicing & Validation Re-parse
Section titled “1. Automatic Scope Splicing & Validation Re-parse”If Branch A reformats code, renames a variable, or moves a function block, and Branch B independently adds logic inside another function, symtrace merge-driver splices the AST scopes cleanly. Before writing the output, it performs a validation re-parse (has_ast_errors()). If any syntax corruption or broken scope is detected, it automatically falls back to standard conflict markers safely.
2. Semantic Conflict Annotations
Section titled “2. Semantic Conflict Annotations”For genuine logic conflicts (e.g., both branches modify the same AST statement differently), symtrace merge-driver writes clear, AST-annotated conflict headers:
<<<<<<< Ours: fn process_user [Renamed 'id' -> 'user_id']let account = fetch_user(user_id);||||||| Baselet user = fetch_user(id);=======let account = fetch_user_by_uuid(id);>>>>>>> Theirs: fn process_user [Modified logic]Configuration Options
Section titled “Configuration Options”Configure merge resolution behavior in .symtracerc or symtrace.toml:
[merge]auto_resolve_formatting = true # Resolve whitespace/formatting conflicts automaticallyauto_resolve_reorders = true # Resolve reordered function/struct definitionsfallback_to_text = true # Fallback to standard 3-way text diff if AST parse failsannotate_semantic_conflicts = true # Add AST entity context to conflict headersDirect CLI Testing
Section titled “Direct CLI Testing”You can test 3-way merge resolution manually on temporary files:
symtrace merge-driver base.rs ours.rs theirs.rs target_path.rsReturns exit code 0 on clean merge, or exit code 1 if conflict markers were written for manual review.