gitsqlite is a Git clean/smudge/diff filter designed to convert SQLite databases into plain text SQL format for version control. This enables meaningful diffs and merges of database changes within Git repositories.
Key Features:
Automatic conversion between .sqlite binary files and human-readable SQL text
Deterministic dumps with consistent float rounding across platforms
Exclusion of SQLite internal/system tables from diffs
Robust handling via temp-file I/O for better reliability
Optional logging for diagnostics
Cross-platform support (Windows, Linux, macOS)
Ideal for developers managing application databases in Git repositories. It provides a transparent way to track database changes, resolve conflicts, and maintain audit trails of schema and data modifications over time.
Installation is available via winget on Windows, making deployment straightforward within organizations.
README
gitsqlite
A Git clean/smudge/diff filter for storing SQLite databases in plain text SQL, enabling meaningful diffs and merges.
Why
Binary SQLite databases are opaque to Git – you can’t easily see changes or resolve conflicts. gitsqlite automatically converts between .sqlite and SQL text on checkout and commit or diff, letting you version SQLite data just like source code.
Git will now store only data changes in the database file, while schema is managed separately. This results in much cleaner diffs that only show INSERT operations.
Quick Start Git Diff
To enable SQL-based diffs for SQLite databases in Git, add the following to your repository's .gitattributes and configure your Git diff driver: (It doesn't matter if it is stored as binary or via smudge/clean.)
Merging SQLite databases is complex and risky for many applications. While gitsqlite enables text-based diffs and basic merging, domain-specific databases often require specialized tools for safe merging.
When NOT to rely on automatic merging:
Sparx Enterprise Architect (.qeax) databases - Use LieberLieber LemonTree for proper model merging
Application-specific databases with complex schemas, constraints, or business logic
Databases with foreign key relationships where merge conflicts could break referential integrity
Production databases where data corruption could have serious consequences
Recommended workflow:
Use gitsqlite for visibility - See what changed in your database commits
Use specialized tools for merging - Domain experts tools understand your data structure
Manual conflict resolution - Review and resolve conflicts using appropriate tools
Test thoroughly - Validate database integrity after any merge operation
gitsqlite is excellent for tracking changes and simple scenarios, but consider it a foundation tool rather than a complete solution for complex database merging.
Installation
Windows (PowerShell):
# AMD64 (Intel/AMD 64-bit)
winget install danielsiegl.gitsqlite
# curl -L -o gitsqlite.exe https://github.com/danielsiegl/gitsqlite/releases/latest/download/gitsqlite-windows-amd64.exe
# ARM64 (Windows on ARM)
# curl -L -o gitsqlite.exe https://github.com/danielsiegl/gitsqlite/releases/latest/download/gitsqlite-windows-arm64.exe
# Move to a directory in your PATH, e.g.:
# Move-Item gitsqlite.exe C:\Windows\System32\
Linux:
# AMD64 (Intel/AMD 64-bit) - using curl
curl -L -o gitsqlite https://github.com/danielsiegl/gitsqlite/releases/latest/download/gitsqlite-linux-amd64
# ARM64 (ARM servers) - using curl
# curl -L -o gitsqlite https://github.com/danielsiegl/gitsqlite/releases/latest/download/gitsqlite-linux-arm64
# Alternative with wget
wget -O gitsqlite https://github.com/danielsiegl/gitsqlite/releases/latest/download/gitsqlite-linux-amd64
chmod +x gitsqlite
sudo mv gitsqlite /usr/local/bin/
macOS:
# Apple Silicon (M1/M2/M3) - using curl
# curl -L -o gitsqlite https://github.com/danielsiegl/gitsqlite/releases/latest/download/gitsqlite-macos-arm64
# Alternative with wget
wget -O gitsqlite https://github.com/danielsiegl/gitsqlite/releases/latest/download/gitsqlite-macos-amd64
chmod +x gitsqlite
sudo mv gitsqlite /usr/local/bin/
From Source (Go):
go install github.com/danielsiegl/gitsqlite@latest
Requirements:
sqlite3 CLI available in PATH (or specify with -sqlite flag)
Go ≥ 1.21 (only needed to build from source)
Usage
gitsqlite operates as a Git clean/smudge/diff filter, automatically converting between binary SQLite databases and SQL text format. The diff operation now takes a database filename as input (not stdin) and streams the SQL dump to stdout for comparison or inspection.
-float-precision - Set the number of digits for rounding float values in SQL output (default: 9). Ensures deterministic dumps and consistent diffs across platforms.
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT);
INSERT INTO users VALUES(1,'John Doe','john@example.com');
INSERT INTO users VALUES(2,'Jane Smith','jane@example.com');
COMMIT;
Convert back to database:
gitsqlite smudge < sample.sql > restored.db
Verify the restoration:
sqlite3 restored.db "SELECT * FROM users;"
Schema/Data Separation Workflow
The schema/data separation feature allows you to store database schema and data separately for cleaner Git workflows and easier diff viewing.
Separate schema and data during clean:
# Extract data-only (INSERT statements) and save schema to separate file
gitsqlite -data-only -schema clean < database.db > data.sql
View the separated files:
# Schema file contains CREATE TABLE statements
cat .gitsqliteschema
# PRAGMA foreign_keys=OFF;
# BEGIN TRANSACTION;
# CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT);
# COMMIT;
# Data file contains INSERT statements
cat data.sql
# PRAGMA foreign_keys=OFF;
# BEGIN TRANSACTION;
# INSERT INTO users VALUES(1,'John Doe','john@example.com');
# INSERT INTO users VALUES(2,'Jane Smith','jane@example.com');
# COMMIT;
Restore database from separated files:
# Combine schema and data back into database
gitsqlite -schema smudge < data.sql > restored.db
Benefit: Cleaner diffs that show only data changes:
# After modifying data, diff will only show INSERT/UPDATE/DELETE changes
gitsqlite -data-only clean < modified.db > modified_data.sql
diff data.sql modified_data.sql