# How to Compare Graph Snapshots Using Graph Diff in Code Review Graph

> Compare graph snapshots effectively with code review graph and its graph diff module. Learn to capture, save, load, and diff snapshots to identify changes in nodes, edges, and communities.

- Repository: [Tirth Kanani/code-review-graph](https://github.com/tirth8205/code-review-graph)
- Tags: how-to-guide
- Published: 2026-07-19

---

**To compare graph snapshots, use the `graph_diff` module to capture the current state with `take_snapshot()`, persist it with `save_snapshot()`, then load two snapshots and run `diff_snapshots()` to detect added or removed nodes, edges, and community migrations.**

The `tirth8205/code-review-graph` repository provides a SQLite-backed `GraphStore` that represents your entire codebase as a knowledge graph. Comparing graph snapshots using graph diff enables you to track exactly how symbols and their relationships evolve between any two points in time, such as before and after a major refactoring.

## Capturing a Graph Snapshot

The `take_snapshot()` function in [`code_review_graph/graph_diff.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/graph_diff.py) walks the `GraphStore` and returns a lightweight dictionary that freeze-frames the graph state. This snapshot records:

- Total node and edge counts via `GraphStore.get_stats()`
- Every node's qualified name, kind, source file, and community assignment via `get_all_nodes()` and `get_all_community_ids()`
- A complete set of edges (source → target : kind) via `get_all_edges()`

```python
from code_review_graph.graph_diff import take_snapshot

snapshot = take_snapshot(my_store)  # my_store is a GraphStore instance

```

Because the snapshot is built entirely through the public `GraphStore` API defined in [`code_review_graph/graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/graph.py), it captures the exact database state without requiring direct SQLite access.

## Persisting Snapshots to Disk

Use `save_snapshot()` to write the snapshot dictionary to a JSON file. The function converts the internal edge set to a sorted list to guarantee stable, deterministic output.

```python
from pathlib import Path
from code_review_graph.graph_diff import save_snapshot

save_snapshot(snapshot, Path("before.json"))

```

This serialization step is essential for comparing graph snapshots across different process executions or after codebase updates.

## Loading and Comparing Snapshots

To perform the comparison, first restore your saved states using `load_snapshot()`, which reads the JSON file and converts the edge list back into a Python `set` for efficient set operations.

```python
from code_review_graph.graph_diff import load_snapshot

before = load_snapshot(Path("before.json"))
after = load_snapshot(Path("after.json"))

```

Next, invoke `diff_snapshots(before, after)` to compute the delta. This function performs set differences on node keys and edge keys, then walks the intersection to detect community ID changes.

```python
from code_review_graph.graph_diff import diff_snapshots

changes = diff_snapshots(before, after)
print(changes["summary"])

```

## Interpreting the Diff Results

The dictionary returned by `diff_snapshots()` contains five key sections:

- **`new_nodes`** and **`removed_nodes`** – Qualified names and full metadata for symbols that were added or deleted.
- **`new_edges`** and **`removed_edges`** – Edge signatures (source, target, kind) representing created or dropped relationships.
- **`community_changes`** – Nodes that remained in the graph but were reassigned to a different community ID.
- **`summary`** – Compact counts of total additions, deletions, and migrations.

Because the underlying data structures are plain Python collections, the diff operation is fast, deterministic, and requires no database connectivity.

## End-to-End Example

The following workflow demonstrates how to compare graph snapshots using graph diff after updating your codebase:

```python
from pathlib import Path
from code_review_graph.graph import GraphStore
from code_review_graph.graph_diff import (
    take_snapshot, save_snapshot, load_snapshot, diff_snapshots,
)

# Initialize the store (e.g., from a temporary DB)

store = GraphStore("tmp_graph.db")

# Populate the store via parsing and indexing...

# Capture the "before" state

before = take_snapshot(store)
save_snapshot(before, Path("snap_before.json"))

# ... make code changes, re-run the indexer ...

# Capture the "after" state

after = take_snapshot(store)
save_snapshot(after, Path("snap_after.json"))

# Load and diff

before = load_snapshot(Path("snap_before.json"))
after = load_snapshot(Path("snap_after.json"))
diff = diff_snapshots(before, after)

print("=== Summary ===")
print(diff["summary"])
print("\nNew nodes (first 5):")
print(diff["new_nodes"][:5])
print("\nRemoved edges (first 5):")
print(diff["removed_edges"][:5])

```

Unit tests validating this behavior are located in [`tests/test_tools.py`](https://github.com/tirth8205/code-review-graph/blob/main/tests/test_tools.py) and [`tests/test_graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/tests/test_graph.py), which verify both the diff logic and the underlying node/edge storage integrity.

## Summary

- **`take_snapshot()`** captures the complete `GraphStore` state—including node metadata, edges, and community assignments—through the public API in [`graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/graph.py).
- **`save_snapshot()`** and **`load_snapshot()`** handle JSON serialization and deserialization, ensuring edge sets are stored as sorted lists for stability but restored as sets for efficient computation.
- **`diff_snapshots()`** executes set operations to identify added or removed nodes and edges, plus tracks community reassignments via intersection analysis.
- All operations read from the SQLite schema indirectly through `GraphStore` methods, eliminating the need for raw database queries.

## Frequently Asked Questions

### Where is the graph diff utility implemented?

The implementation resides in [`code_review_graph/graph_diff.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/graph_diff.py), which imports and utilizes the `GraphStore` class defined in [`code_review_graph/graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/graph.py).

### What format does the snapshot use for storage?

Snapshots are persisted as JSON files. Edge data is converted to a sorted list during serialization to ensure deterministic output, then transformed back into a Python `set` when loaded to optimize diff performance.

### Can the diff detect when a node changes communities without being deleted?

Yes. The `community_changes` key in the diff result contains entries for nodes that remained in the graph but were assigned to a different community ID, allowing you to track modular restructuring.

### Is the snapshot process dependent on specific database transactions?

No. The snapshot reads from the live `GraphStore` using methods like `get_all_nodes()` and `get_all_edges()`, capturing the state at the exact moment of the call regardless of ongoing transactions.