feat: git mind diff — graph diff between commits (#203)#204
feat: git mind diff — graph diff between commits (#203)#204flyingrobots merged 5 commits intomainfrom
Conversation
Introduces src/diff.js with:
- diffSnapshots() — pure comparison of two materialized graphs
- computeDiff() — orchestrator (resolve epochs + materialize + diff)
- parseDiffRefs() — CLI argument parser for range/two-arg/shorthand syntax
- edgeKey(), compareEdge(), computeSummary() — internal helpers
Three graph instances needed because materialize({ ceiling }) is
destructive. System prefixes (decision, commit, epoch) excluded from
diff output. Prefix filter requires both edge endpoints to match.
25 tests covering: - diffSnapshots: node/edge detection, system node exclusion, prefix filtering, both-endpoint rule, summary computation - computeDiff: end-to-end epoch resolution, nearest fallback, same-tick empty diff, non-linear branch+merge history - parseDiffRefs: range syntax, two-arg, shorthand, error cases - compareEdge: deterministic sort ordering
- formatDiff() + renderDiffTable() in format.js for TTY output - diff() command in commands.js following standard pattern - parseDiffRefs + case 'diff' in CLI entry point - computeDiff + diffSnapshots exported from public API - Usage text updated with diff command docs - GITMIND_DEBUG env var controls stats timing output
- v2.0.0-alpha.5 changelog section for git mind diff - New "Comparing graph snapshots" guide section with usage, prefix filtering, JSON versioning, and nearest-epoch fallback - CLI reference entry for git mind diff - Table of contents updated
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughAdds a new "diff" feature: CLI wiring, command handler, core diff engine, formatter, public exports, and comprehensive tests to compute and display graph differences between two commits (JSON or human-readable). Changes
Sequence DiagramsequenceDiagram
actor User
participant CLI as CLI Handler
participant Commands as Command Handler
participant Diff as Diff Engine
participant Graph as Graph Resolver
participant Format as Formatter
participant Output as Output
User->>CLI: git mind diff A..B
CLI->>CLI: parse args & flags
CLI->>Diff: parseDiffRefs(args)
Diff-->>CLI: {refA, refB}
CLI->>Commands: diff(cwd, refA, refB, opts)
Commands->>Diff: computeDiff(cwd, refA, refB, opts)
Diff->>Graph: resolve refA -> epoch/tick
Diff->>Graph: resolve refB -> epoch/tick
Graph-->>Diff: epoch ceilings
Diff->>Graph: materialize(ceiling A)
Graph-->>Diff: graph snapshot A
Diff->>Graph: materialize(ceiling B)
Graph-->>Diff: graph snapshot B
Diff->>Diff: diffSnapshots(graphA, graphB, opts)
Diff-->>Commands: DiffResult
alt opts.json
Commands->>Output: JSON.stringify(DiffResult)
else
Commands->>Format: formatDiff(DiffResult)
Format-->>Commands: formatted string
Commands->>Output: write formatted string
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 6✅ Passed checks (6 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@src/diff.js`:
- Around line 274-300: The same-tick shortcut returns zero totals which
misrepresents an unchanged graph; update the early-return object (the block that
checks tickA === tickB) to mark the result as skipped so consumers can
distinguish "unchanged" from "empty": add a flag like stats.skipped: true (or a
top-level skipped: true) in the returned object and keep existing node/edge
counts unchanged or set totals to null to indicate "not computed"; make the
change where tickA, tickB, resultA, resultB are used and ensure the
DiffResult/Stats shape (referenced by nodes.total, edges.total, and
stats.materializeMs/diffMs) reflects the new skipped flag so downstream JSON
consumers can detect the shortcut.
- Fix --prefix value leaking into positional args: flag values like `task` from `--prefix task` were incorrectly treated as ref arguments. Extracted collectDiffPositionals() helper that skips consumed values. - Add stats.sameTick flag to same-tick shortcut so JSON consumers can distinguish "unchanged graph" from "empty graph" (was returning 0/0). - 5 new regression tests (collectDiffPositionals + sameTick assertion). - CHANGELOG updated with fixes.
Summary
git mind diffcommand to compare the knowledge graph between two historical commitsA..B), two-arg (A B), shorthand (A→A..HEAD),--prefixscoping, and--jsonoutput withschemaVersion: 1Closes #203
What changed
src/diff.jsdiffSnapshots,computeDiff,parseDiffRefstest/diff.test.jssrc/cli/format.jsformatDiff,renderDiffTablesrc/cli/commands.jsdiffcommand functionbin/git-mind.jssrc/index.jsCHANGELOG.mdGUIDE.mdDesign decisions
materialize({ ceiling })is destructive. All three read from the same git CAS — no I/O duplication.decision,commit,epoch) matchessrc/export.jspattern--prefix: edges only included if both endpoints pass the filterschemaVersion: 1in JSON output for forward compatibility(type, source, target)Test plan
npx vitest run test/diff.test.js— 25 tests passnpx vitest run— 337 tests across 20 files, all greengit mind diff HEAD~3..HEAD,--json,--prefix, error casesSummary by CodeRabbit