Skip to main content

Git-like Versioning

Added in v1.1.0. DeepDiff DB ships a full Git-inspired versioning system for database diffs. It lets you commit schema and data diff snapshots as immutable objects, browse history, compare any two points in time, generate rollback SQL, and manage parallel lines of schema evolution through branches — all without a live database connection after the commit is taken.


Core Concepts

The .deepdiffdb/ repository

version init creates a local object store in the current directory:

.deepdiffdb/
HEAD ← symbolic ref: "ref: refs/heads/main"
config ← verified GitHub identity (0o600, token never stored)
objects/
<2-hex>/
<62-hex> ← zlib-compressed commit object (Git fanout layout)
refs/
heads/
main ← tip hash for the main branch
<branch> ← one file per branch

Each commit object is self-contained: it stores the full schema.DiffResult, content.DataDiff, both schema snapshots (prod + dev), author, message, timestamp, parent hash, and a SHA-256 content-addressable hash. The entire history is portable — commit .deepdiffdb/ to share it with your team, or add .deepdiffdb/config to .gitignore to keep your identity local.

Verified Authorship

version init prompts you to authenticate with GitHub via the device flow. Once authenticated, every version commit automatically uses github:<username> as the author — no --author flag needed. The access token is discarded after identity verification; only the username is stored.

Commits

A commit is a point-in-time snapshot of the diff between your prod and dev databases. It is created with version commit:

deepdiffdb version commit --message "V2: add reviews table" --author "Alice"

DeepDiff DB connects to both databases, runs a full schema and data diff, and stores the result as a new object. The commit is linked to its parent, forming a chain you can walk backward.

Branches

Branches let you track parallel lines of schema evolution — for example, a feature branch for experimental schema work running alongside main for production hotfixes.

main    ──● V1 ──● V2 (hotfix)

feature └──● V2 (experimental index)

HEAD is a symbolic ref that points to the active branch. version commit always advances the checked-out branch tip; all other branch tips are unchanged.


Typical Workflow

# 1. Initialise once per project — authenticate with GitHub for verified authorship
deepdiffdb version init
# → prompts for GitHub device flow (no browser redirect needed)
# → stores {"github_user":"iamvirul"} in .deepdiffdb/config; token discarded

# 2. Commit baseline snapshot (prod == dev at project start)
# Author resolved automatically from .deepdiffdb/config
deepdiffdb version commit \
--config deepdiffdb.config.yaml \
--message "V1: baseline e-commerce schema"

# 3. Create a feature branch for experimental schema work
deepdiffdb version branch feature
deepdiffdb version checkout feature

# 4. Developer applies schema changes to the dev database
# (ALTER TABLE, CREATE TABLE, etc.)

# 5. Commit the drift on the feature branch
deepdiffdb version commit \
--config deepdiffdb.config.yaml \
--message "V2: add reviews table and avg_rating column"

# 6. Switch back to main for a production hotfix
deepdiffdb version checkout main
deepdiffdb version commit \
--config deepdiffdb.config.yaml \
--message "V2: hotfix — drop unused index"

# 7. Visualise the full branch history
deepdiffdb version tree

# 8. See what changed between two commits
deepdiffdb version diff <hash_v1> <hash_v2>

# 9. Generate rollback SQL for a commit
deepdiffdb version rollback --out rollback_v2.sql <hash_v2>

Commands

CommandDescription
version initInitialise a .deepdiffdb/ repository
version commitSnapshot the current diff as a new commit
version logShow commit history newest-first
version diffCompare schema evolution between two commits
version rollbackGenerate rollback SQL for a commit
version branchList or create branches
version checkoutSwitch active branch
version treeASCII commit graph across all branches

Example: ASCII Commit Tree

| * e2a3d002 (feature)        2026-04-01  V2: experimental index
* | 761e26c5 (HEAD -> main) 2026-04-01 V2: hotfix — drop unused index
|/
* 18bf631b 2026-04-01 V1: baseline e-commerce schema

Each column in the graph represents a branch lane:

  • * — commit belongs to this lane's branch
  • | — lane is active but commit is on another branch
  • (HEAD -> main) — the currently checked-out branch
  • (feature) — a non-current branch tip

Example: Rollback SQL

Given a commit that added a reviews table and a customer_email column, version rollback produces:

BEGIN;

-- Schema Migration Script
-- Generated by DeepDiff DB for mysql

-- DROP TABLES (present in prod but not in dev)
-- WARNING: These operations will delete data!
-- DROP TABLE `reviews`;

-- Table: orders
-- DROP COLUMNS (present in prod but not in dev)
-- ALTER TABLE `orders` DROP COLUMN `customer_email`;

COMMIT;

Destructive operations are commented out by default. Uncomment the statements you want to apply, review them, and execute against the target database.


Storage Details

Objects are stored using Git's 2-character fanout layout to prevent directory entry limits at scale:

.deepdiffdb/objects/<first-2-chars-of-hash>/<remaining-62-chars>

Each object is zlib-compressed JSON. The hash is computed as SHA-256("commit <size>\x00<json>") — the same scheme Git uses for blob objects, ensuring content-addressability.


See Also