Keep your database in sync with your git branches.
db-git is a developer tool for projects where database state follows code
changes: schema migrations, seed data, experimental feature work, and branch
switching during reviews. It installs a git post-checkout hook and keeps your
local database aligned with the branch you are working on.
Status: PostgreSQL is supported today; support for additional database engines is planned.
- Automatic database handling on
git checkout - Two workflows:
shared: one database, saved and restored per branchper-branch: one database per branch
- PostgreSQL support today, with plans for more database backends
- Two PostgreSQL snapshot strategies:
template: fast database clones usingCREATE DATABASE ... TEMPLATEpgdump: portable snapshots usingpg_dumpandpg_restore
- Manual
save,restore,create,reset,list,status, andprunecommands - Safe hook behavior: checkout is never blocked by db-git failures
- Rich terminal output and local state stored under
.git/db-git/
uv tool install db-git # or pip install db-gitRun this from inside a git repository:
db-git init --database-url postgresql://postgres:postgres@localhost:5432/myappInteractive init will ask:
- Whether to use
sharedorper-branchmode - Whether to use
templateorpgdumpstrategy - What to do when active connections block database operations
- Whether to install the git
post-checkouthook
After setup, switch branches normally:
git checkout feature/authIn shared mode, db-git saves the previous branch database and restores the
new branch snapshot if one exists.
In per-branch mode, db-git creates or selects a database named from the
current branch, for example:
myapp__feature__auth
Because the database name changes per branch, your application server also
needs to connect to the branch database. For example, when working on
feature/auth, point your app's DATABASE_URL at myapp__feature__auth.
Shared mode keeps one database name from DATABASE_URL.
Use this when:
- You want one familiar local database name
- You want branch-specific snapshots
- You are comfortable with db-git dropping and restoring that local database during branch switches
Per-branch mode creates a separate database for each branch. The configured default branch keeps the original database name and acts as the seed database.
Use this when:
- You want branch databases to persist independently
- You prefer creating new databases over repeatedly restoring one shared database
The template strategy uses PostgreSQL database cloning:
CREATE DATABASE target TEMPLATE source;It is usually fast, but requires sufficient PostgreSQL privileges and can be blocked by active connections to the source or target database.
The pgdump strategy uses pg_dump and pg_restore.
It is slower than template, but can be a better fit when template cloning is
not available. It requires PostgreSQL client tools to be installed locally.
db-git init --database-url postgresql://user:password@localhost:5432/myappUseful options:
db-git init \
--database-url postgresql://user:password@localhost:5432/myapp \
--mode per-branch \
--strategy template \
--on-active-connections terminateSkip hook installation:
db-git init --database-url postgresql://localhost/myapp --no-hookdb-git status
db-git listSave the current branch database:
db-git saveRestore the current branch database:
db-git restoreSave or restore a specific branch:
db-git save main
db-git restore feature/authCreate a branch database before checking out the branch:
db-git create feature/authDrop and recreate a branch database from the seed database:
db-git reset feature/authThe default branch database cannot be reset because it is the seed for other branch databases.
Preview stale snapshots or branch databases:
db-git prune --dry-runRemove stale snapshots or branch databases:
db-git prune --yesInstall or reinstall the checkout hook:
db-git hook installRemove the checkout hook:
db-git hook removeTemporarily disable db-git without removing the hook:
db-git disable
db-git enableYou can also skip hook behavior for a single checkout:
DB_GIT_SKIP=1 git checkout other-branchdb-git init writes .db-git.toml at the repository root.
Example:
database_url = "postgresql://postgres:postgres@localhost:5432/myapp"
mode = "per-branch"
default_branch = "main"
strategy = "template"
on_active_connections = "terminate"Supported configuration keys:
| Key | Description | Default |
|---|---|---|
database_url |
Database connection URL | required |
mode |
shared or per-branch |
shared |
default_branch |
Seed branch for per-branch mode | main |
strategy |
template or pgdump |
required |
on_active_connections |
terminate or fail |
terminate |
snapshot_dir |
Shared-mode snapshot metadata/dump directory | .git/db-git/snapshots |
max_snapshots |
Snapshot count kept by prune logic | 20 |
force_terminate_timeout_ms |
Active connection termination timeout | 5000 |
Configuration precedence:
- Built-in defaults
.db-git.toml- Environment variables
- CLI options
Environment variables:
DATABASE_URL
DB_GIT_DATABASE_URL
DB_GIT_MODE
DB_GIT_STRATEGY
DB_GIT_ON_ACTIVE_CONNECTIONS
DB_GIT_SNAPSHOT_DIR
DB_GIT_MAX_SNAPSHOTS
DB_GIT_FORCE_TERMINATE_TIMEOUT_MSDB_GIT_DATABASE_URL takes precedence over DATABASE_URL.
Stop your development server, database console, migration watcher, or GUI client, then retry.
Alternatively, configure:
on_active_connections = "terminate"Your PostgreSQL user may need superuser privileges or membership in
pg_signal_backend to terminate sessions owned by other users.
db-git disable
git checkout some-branch
db-git enableOr for one command:
DB_GIT_SKIP=1 git checkout some-branchDB_GIT_DEBUG=1 db-git statusInstall dependencies:
uv sync --group devRun checks:
uv run ruff check .
uv run mypy src tests
uv run pytest tests/unitRun the full nox suite:
noxMIT