Skip to content

feat: git mind diff — graph diff between commits (#203)#204

Merged
flyingrobots merged 5 commits intomainfrom
roadmap/chronicle
Feb 14, 2026
Merged

feat: git mind diff — graph diff between commits (#203)#204
flyingrobots merged 5 commits intomainfrom
roadmap/chronicle

Conversation

@flyingrobots
Copy link
Owner

@flyingrobots flyingrobots commented Feb 14, 2026

Summary

  • Adds git mind diff command to compare the knowledge graph between two historical commits
  • Resolves git refs → epoch markers → Lamport ticks, materializes two separate graph snapshots, and reports node/edge additions and removals with summary tables
  • Supports range syntax (A..B), two-arg (A B), shorthand (AA..HEAD), --prefix scoping, and --json output with schemaVersion: 1

Closes #203

What changed

File Action Role
src/diff.js NEW Core diff: diffSnapshots, computeDiff, parseDiffRefs
test/diff.test.js NEW 25 tests (unit, integration, parser, edge cases)
src/cli/format.js MOD formatDiff, renderDiffTable
src/cli/commands.js MOD diff command function
bin/git-mind.js MOD CLI case + usage text
src/index.js MOD Public API export
CHANGELOG.md MOD v2.0.0-alpha.5 section
GUIDE.md MOD "Comparing graph snapshots" section + CLI reference

Design decisions

  • Three graph instances (resolver + A + B) because materialize({ ceiling }) is destructive. All three read from the same git CAS — no I/O duplication.
  • System prefix exclusion (decision, commit, epoch) matches src/export.js pattern
  • Both-endpoint rule for --prefix: edges only included if both endpoints pass the filter
  • schemaVersion: 1 in JSON output for forward compatibility
  • Deterministic ordering: nodes lexicographic, edges by (type, source, target)

Test plan

  • npx vitest run test/diff.test.js — 25 tests pass
  • npx vitest run — 337 tests across 20 files, all green
  • Manual smoke: git mind diff HEAD~3..HEAD, --json, --prefix, error cases

Summary by CodeRabbit

  • New Features
    • Added a diff command to compare two snapshots (supports --json and --prefix). Outputs a human-readable diff with per-node/edge counts, “by prefix” and “by type” summaries, and optional timing info.
  • Bug Fixes
    • Improved error messages and non-zero exit on invalid or unresolved diff references.
  • Tests
    • Comprehensive test suite validating diff logic, parsing, filtering, summaries, and edge sorting.

CI Bot added 4 commits February 13, 2026 19:00
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
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 14, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds 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

Cohort / File(s) Summary
Core Diff Engine
src/diff.js
New module implementing computeDiff, diffSnapshots, diff parsing (parseDiffRefs), edge/node comparison utilities, summaries, epoch resolution, and timing/stats.
CLI Entrypoint
bin/git-mind.js
Added diff command parsing (A..B / posargs), flags --json and --prefix, and dispatch to command handler with error handling.
Command Handler
src/cli/commands.js
New exported diff(cwd, refA, refB, opts) calling computeDiff and emitting JSON or formatted output; imports computeDiff and formatDiff.
Output Formatting
src/cli/format.js
Added formatDiff() and helper renderDiffTable() to render endpoints, node/edge summaries, per-prefix/type tables, and optional timing debug info.
Public API Exports
src/index.js
Re-exports computeDiff and diffSnapshots from src/diff.js.
Tests
test/diff.test.js
Extensive tests for diffSnapshots, computeDiff, parseDiffRefs, collectDiffPositionals, compareEdge, epoch resolution behavior, filtering, and summary metrics.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

  • feat: time-travel via epoch markers (git mind at) #202 — Related: diff relies on epoch/time-travel APIs (resolving refs to epochs/ticks and materializing graphs), which this change uses.
  • #203 — This PR implements the requested "git mind diff" feature: CLI, JSON output, epoch fallback, and tests matching the issue objectives.

Poem

🐰 With twitching whiskers, I bound and sniff,

Through nodes and edges, I hop and skiff,
I count what's lost and what is new,
A little hop — the graph's review! 🎋✨

🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding a graph diff feature to git mind for comparing commits. It is specific, directly related to the changeset, and avoids vague terminology.
Linked Issues check ✅ Passed The PR implementation fully addresses all coding objectives from issue #203: implements git mind diff command with range/two-arg/shorthand ref forms, materializes two graph snapshots, computes node/edge diffs, provides --json and --prefix options, handles missing epochs with fallback, includes 25 comprehensive tests, and exports public API functions.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing the git mind diff feature: core diff logic (src/diff.js), CLI command and formatting (bin/git-mind.js, src/cli/commands.js, src/cli/format.js), tests (test/diff.test.js), and public exports (src/index.js). No unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 92.31% which is sufficient. The required threshold is 80.00%.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch roadmap/chronicle

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
@flyingrobots flyingrobots merged commit 8f4c7e9 into main Feb 14, 2026
5 of 6 checks passed
@flyingrobots flyingrobots deleted the roadmap/chronicle branch February 14, 2026 03:51
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.

feat: graph diff between commits (git mind diff)

1 participant