Semantic (AST) diffing
zev sdiff compares Zig code by function (added, removed, signature or body changed) from the compiler's own parser, not lines of text.
Search for a command to run…
zev sdiff compares Zig code by function (added, removed, signature or body changed) from the compiler's own parser, not lines of text.
zev sdiff computes a structural diff for Zig source files by parsing both versions with std.zig.Ast — Zig's own compiler-grade AST parser — rather than comparing text lines.
For each top-level or struct-method function, zev extracts its name, a normalized signature (parameter types and return type, read directly from the parsed source), and a hash of its body's source text. Comparing old and new versions of a file produces one of:
added — a function present only in the new versionremoved — a function present only in the old versionsignature_changed — same function name, different parameter types or return typebody_changed — same name, same signature, different bodylikely_rename — a function that disappeared under one name and reappeared under another with an identical body hashA real example, run through the actual zev sdiff command:
≈ fn body_will_change body changed≈ fn sig_will_change signature changed: (i32) i32 -> (i32, i32) i32↔ fn calc -> calculate_total identical body- fn will_be_removed removed+ fn brand_new_function addedA rename is detected by matching a disappeared function against an appeared one with an identical body hash — genuinely reliable when a function is renamed without also changing its implementation. If a function's name and its body both change in the same edit, it is reported as a plain removal and addition, not a rename, because there is no reliable signal connecting the two versions in that case.
Duplicate function names are handled deliberately conservatively: if a name appears more than once in either version of a file (for example, two different structs each defining their own init), that name is excluded from direct matching entirely and falls through to rename detection or added/removed, rather than risk pairing the wrong two functions together under a shared name.
Semantic diffing is wired into zev's existing FileDiff/SemanticChange infrastructure, the same structure a simpler, text-pattern-based diff already used for other languages. Zig files are dispatched to the AST-based diff; every other supported language continues to use the existing text-heuristic path. If a Zig file fails to parse cleanly — mid-edit syntax errors, for instance — the AST diff falls back to that same text heuristic automatically, so a diff is still produced rather than nothing at all.