Zero-config, Git-native local database branching for PostgreSQL, MySQL, and SQLite.
Stop dropping your local database every time you switch Git branches.
Every developer working with Docker, local PostgreSQL, MySQL, or SQLite has suffered this loop:
1. You work on `feature/checkout-v2`.
βββ Ran migrations: added table `stripe_orders`, added column `users.billing_tier NOT NULL`.
2. Urgent production bug alert! You run:
βββ `git checkout main`
3. You start the app or run tests on `main`.
4. π₯ CRASH:
βββ ActiveRecord::PendingMigrationError / PrismaClientKnownRequestError:
"column users.billing_tier does not exist" or "schema mismatch detected".
docker compose down -v && docker compose up -dfeature/checkout-v2 before switching, only to lose experimental test data..env Nightmare: Manually maintaining DATABASE_URL_DEV, DATABASE_URL_CHECKOUT, and editing .env on every branch change.BranchBase brings instant, zero-copy database branching directly to your local machine and Docker containers.
+---------------------------+
| Developer Machine |
+---------------------------+
|
`git checkout branch-b`
|
v
[ BranchBase Git Hook ]
|
+--------------------+--------------------+
| |
(Detects new branch) (Zero-Copy Snapshot)
| |
v v
+---------------------------------------+ +------------------------------------+
| BranchBase Proxy (Port 5432) | | Local Database (PostgreSQL) |
+---------------------------------------+ +------------------------------------+
| - App connection string NEVER changes | | - `db_project_main` (frozen) |
| - Automatically routes queries to the | | - `db_project_branch_b` (active) |
| active Git branch database! | | (Created instantly via TEMPLATE) |
+---------------------------------------+ +------------------------------------+
CREATE DATABASE ... TEMPLATE or filesystem copy-on-write (reflink/APFS/Btrfs for SQLite).DATABASE_URL=postgres://user:pass@localhost:5432/myapp never changes. The local proxy automatically inspects which Git branch is active in your working directory and routes traffic to that branch's database.post-checkout and post-merge. You simply use standard git checkout or git switch.prune): When you delete or merge a Git branch, branchbase safely tears down the associated ephemeral database.| Command | What it does |
|---|---|
branchbase init | Interactively inspect repository and generate .branchbase.json |
branchbase proxy | Start the local transparent TCP routing proxy (default port: 5432) |
branchbase status | Display the active Git branch, sanitized name, target DB, and driver status |
branchbase list | List all active and ephemeral databases managed by BranchBase with disk usage |
branchbase switch <branch> | Manually switch or provision an isolated database for a specific branch |
branchbase hooks install | Install automated post-checkout and post-merge hooks into .git/hooks/ |
branchbase hooks status | Inspect Git hooks installation and activity status |
branchbase prune | Detect and delete databases associated with merged or deleted Git branches |
branchbase version | Print the current BranchBase version |
branchbase/
βββ cmd/
β βββ branchbase/
β βββ main.go # CLI entry point (subcommands & signal handling)
βββ internal/
β βββ config/ # Configuration loader (.branchbase.json / .yaml)
β βββ driver/ # Database engine interfaces & registry
β β βββ driver.go # Core Driver interface contract
β β βββ postgres/ # PostgreSQL engine (TEMPLATE cloning)
β β βββ sqlite/ # SQLite engine (CoW / Reflink snapshots)
β βββ git/ # Git HEAD inspector and branch sanitization
β β βββ resolver.go # Non-subshell .git/HEAD resolution
β β βββ resolver_test.go # Table-driven unit test suite
β βββ hook/ # Automated Git hook manager (post-checkout/merge)
β β βββ hook.go # Non-intrusive hook installer
β β βββ hook_test.go # Hook lifecycle test suite
β βββ proxy/ # Transparent TCP proxy & wire routing
β βββ pgwire/ # PostgreSQL wire-protocol StartupMessage rewriter
β β βββ pgwire.go # Packet parser & database replacer
β β βββ pgwire_test.go # Protocol unit test suite
β βββ proxy.go # Zero-overhead bidirectional TCP forwarder
βββ .agents/ # Custom Agent skills & development workflows
βββ .github/ # CI workflows, issue templates, dependabot
βββ ARCHITECTURE.md # Detailed system design & sequence diagrams
βββ CONTRIBUTING.md # Contributor guide & driver creation tutorial
βββ SETUP.md # Local developer environment setup guide
βββ SECURITY.md # Security policy & private vulnerability reporting
βββ CODE_OF_CONDUCT.md # Contributor Covenant v2.1
βββ CHANGELOG.md # Keep a Changelog version history
βββ branchbase.example.yaml # Annotated configuration specification
βββ go.mod # Go 1.22+ module definition
git checkout <branch>, BranchBase's hook (.git/hooks/post-checkout) detects the branch transition in under 5ms by reading .git/HEAD./ or - in branch names (e.g. feature/stripe-v2) are converted into safe database identifiers (feature_stripe_v2).CREATE DATABASE <target> TEMPLATE <source>; (instant CoW clone).PRAGMA wal_checkpoint(TRUNCATE); and performs a filesystem reflink/clone (clonefile() or FICLONE).localhost:5432, the BranchBase proxy intercepts the connection, resolves the active branch database, and forwards traffic seamlessly.main, running branchbase prune removes the ephemeral database, freeing disk space.External engines are pluggable by design. Adding a new database driver requires just 1 package and 1 interface implementation:
// internal/driver/driver.go
type Driver interface {
Name() string
Ping(ctx context.Context) error
BranchExists(ctx context.Context, branchName string) (bool, error)
CreateBranch(ctx context.Context, sourceBranch, targetBranch string) error
DeleteBranch(ctx context.Context, branchName string) error
ListBranches(ctx context.Context) ([]BranchInfo, error)
}
internal/driver/<engine>/<engine>.go.Driver interface.driver.Register("<engine>", factory) in init().cd my-awesome-project
branchbase init
branchbase proxy
# Branch to a new feature:
git checkout -b feature/stripe-billing
# Run migrations freely:
npx prisma migrate dev # or rails db:migrate / alembic upgrade head
# Switch back to main whenever you want:
git checkout main
# Proxy immediately routes traffic back to your main database! No migration errors!
Thinking about contributing? We'd love to have you!
good first issue label for onboarding tasks.To report a vulnerability privately, please see SECURITY.md or use GitHub Private Vulnerability Reporting.
If you find BranchBase useful in your daily development or it saved you hours of debugging migration mismatches, consider supporting ongoing development:
Your sponsorship helps fund test infrastructure, multi-database driver maintenance, and cross-platform packaging!
Licensed under the MIT License.
5 commits
3 commits
Go
100.0%
Zero-config, Git-native local database branching for PostgreSQL, MySQL, and SQLite.
Stop dropping your local database every time you switch Git branches.
Every developer working with Docker, local PostgreSQL, MySQL, or SQLite has suffered this loop:
1. You work on `feature/checkout-v2`.
βββ Ran migrations: added table `stripe_orders`, added column `users.billing_tier NOT NULL`.
2. Urgent production bug alert! You run:
βββ `git checkout main`
3. You start the app or run tests on `main`.
4. π₯ CRASH:
βββ ActiveRecord::PendingMigrationError / PrismaClientKnownRequestError:
"column users.billing_tier does not exist" or "schema mismatch detected".
docker compose down -v && docker compose up -dfeature/checkout-v2 before switching, only to lose experimental test data..env Nightmare: Manually maintaining DATABASE_URL_DEV, DATABASE_URL_CHECKOUT, and editing .env on every branch change.BranchBase brings instant, zero-copy database branching directly to your local machine and Docker containers.
+---------------------------+
| Developer Machine |
+---------------------------+
|
`git checkout branch-b`
|
v
[ BranchBase Git Hook ]
|
+--------------------+--------------------+
| |
(Detects new branch) (Zero-Copy Snapshot)
| |
v v
+---------------------------------------+ +------------------------------------+
| BranchBase Proxy (Port 5432) | | Local Database (PostgreSQL) |
+---------------------------------------+ +------------------------------------+
| - App connection string NEVER changes | | - `db_project_main` (frozen) |
| - Automatically routes queries to the | | - `db_project_branch_b` (active) |
| active Git branch database! | | (Created instantly via TEMPLATE) |
+---------------------------------------+ +------------------------------------+
CREATE DATABASE ... TEMPLATE or filesystem copy-on-write (reflink/APFS/Btrfs for SQLite).DATABASE_URL=postgres://user:pass@localhost:5432/myapp never changes. The local proxy automatically inspects which Git branch is active in your working directory and routes traffic to that branch's database.post-checkout and post-merge. You simply use standard git checkout or git switch.prune): When you delete or merge a Git branch, branchbase safely tears down the associated ephemeral database.| Command | What it does |
|---|---|
branchbase init | Interactively inspect repository and generate .branchbase.json |
branchbase proxy | Start the local transparent TCP routing proxy (default port: 5432) |
branchbase status | Display the active Git branch, sanitized name, target DB, and driver status |
branchbase list | List all active and ephemeral databases managed by BranchBase with disk usage |
branchbase switch <branch> | Manually switch or provision an isolated database for a specific branch |
branchbase hooks install | Install automated post-checkout and post-merge hooks into .git/hooks/ |
branchbase hooks status | Inspect Git hooks installation and activity status |
branchbase prune | Detect and delete databases associated with merged or deleted Git branches |
branchbase version | Print the current BranchBase version |
branchbase/
βββ cmd/
β βββ branchbase/
β βββ main.go # CLI entry point (subcommands & signal handling)
βββ internal/
β βββ config/ # Configuration loader (.branchbase.json / .yaml)
β βββ driver/ # Database engine interfaces & registry
β β βββ driver.go # Core Driver interface contract
β β βββ postgres/ # PostgreSQL engine (TEMPLATE cloning)
β β βββ sqlite/ # SQLite engine (CoW / Reflink snapshots)
β βββ git/ # Git HEAD inspector and branch sanitization
β β βββ resolver.go # Non-subshell .git/HEAD resolution
β β βββ resolver_test.go # Table-driven unit test suite
β βββ hook/ # Automated Git hook manager (post-checkout/merge)
β β βββ hook.go # Non-intrusive hook installer
β β βββ hook_test.go # Hook lifecycle test suite
β βββ proxy/ # Transparent TCP proxy & wire routing
β βββ pgwire/ # PostgreSQL wire-protocol StartupMessage rewriter
β β βββ pgwire.go # Packet parser & database replacer
β β βββ pgwire_test.go # Protocol unit test suite
β βββ proxy.go # Zero-overhead bidirectional TCP forwarder
βββ .agents/ # Custom Agent skills & development workflows
βββ .github/ # CI workflows, issue templates, dependabot
βββ ARCHITECTURE.md # Detailed system design & sequence diagrams
βββ CONTRIBUTING.md # Contributor guide & driver creation tutorial
βββ SETUP.md # Local developer environment setup guide
βββ SECURITY.md # Security policy & private vulnerability reporting
βββ CODE_OF_CONDUCT.md # Contributor Covenant v2.1
βββ CHANGELOG.md # Keep a Changelog version history
βββ branchbase.example.yaml # Annotated configuration specification
βββ go.mod # Go 1.22+ module definition
git checkout <branch>, BranchBase's hook (.git/hooks/post-checkout) detects the branch transition in under 5ms by reading .git/HEAD./ or - in branch names (e.g. feature/stripe-v2) are converted into safe database identifiers (feature_stripe_v2).CREATE DATABASE <target> TEMPLATE <source>; (instant CoW clone).PRAGMA wal_checkpoint(TRUNCATE); and performs a filesystem reflink/clone (clonefile() or FICLONE).localhost:5432, the BranchBase proxy intercepts the connection, resolves the active branch database, and forwards traffic seamlessly.main, running branchbase prune removes the ephemeral database, freeing disk space.External engines are pluggable by design. Adding a new database driver requires just 1 package and 1 interface implementation:
// internal/driver/driver.go
type Driver interface {
Name() string
Ping(ctx context.Context) error
BranchExists(ctx context.Context, branchName string) (bool, error)
CreateBranch(ctx context.Context, sourceBranch, targetBranch string) error
DeleteBranch(ctx context.Context, branchName string) error
ListBranches(ctx context.Context) ([]BranchInfo, error)
}
internal/driver/<engine>/<engine>.go.Driver interface.driver.Register("<engine>", factory) in init().cd my-awesome-project
branchbase init
branchbase proxy
# Branch to a new feature:
git checkout -b feature/stripe-billing
# Run migrations freely:
npx prisma migrate dev # or rails db:migrate / alembic upgrade head
# Switch back to main whenever you want:
git checkout main
# Proxy immediately routes traffic back to your main database! No migration errors!
Thinking about contributing? We'd love to have you!
good first issue label for onboarding tasks.To report a vulnerability privately, please see SECURITY.md or use GitHub Private Vulnerability Reporting.
If you find BranchBase useful in your daily development or it saved you hours of debugging migration mismatches, consider supporting ongoing development:
Your sponsorship helps fund test infrastructure, multi-database driver maintenance, and cross-platform packaging!
Licensed under the MIT License.
5 commits
3 commits
Go
100.0%