oscarbol09/branchbase

Zero-config, Git-native local database branching for PostgreSQL, MySQL, and SQLite.

3

stars

8

commits

Go

primary language

Sep 6, 2026

updated

branching
database
developer-tools
devops
docker
git
golang
postgres
sqlite

README

BranchBase 🌿

Zero-config, Git-native local database branching for PostgreSQL, MySQL, and SQLite.
Stop dropping your local database every time you switch Git branches.

BranchBase CI Go Version License: MIT PRs Welcome Good First Issues GitHub Sponsors Support on Ko-Fi


⚑ The Problem: The "Git vs. Local Database" Friction

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".

How developers waste hours today:

  • The Nuclear Option: docker compose down -v && docker compose up -d
    (Loses all your test seeds, logins, and mocked state. Takes minutes to re-seed).
  • The Manual Rollback Dance: Trying to rollback migrations on feature/checkout-v2 before switching, only to lose experimental test data.
  • The .env Nightmare: Manually maintaining DATABASE_URL_DEV, DATABASE_URL_CHECKOUT, and editing .env on every branch change.
  • Cloud Branching (Neon, PlanetScale): Great developer experience, but proprietary, paid, and requires an internet connection. It doesn't work for offline development or standard local Docker setups.

πŸš€ The Solution: BranchBase

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) |
+---------------------------------------+   +------------------------------------+

Key Highlights

  • ⚑ Instant Branching: Creates a fresh, isolated branch database in milliseconds using PostgreSQL CREATE DATABASE ... TEMPLATE or filesystem copy-on-write (reflink/APFS/Btrfs for SQLite).
  • πŸ”Œ Transparent Connection Proxy: Your app's 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.
  • 🎣 Automated Git Hook: Hooks into post-checkout and post-merge. You simply use standard git checkout or git switch.
  • 🧹 Automatic Cleanup (prune): When you delete or merge a Git branch, branchbase safely tears down the associated ephemeral database.
  • πŸ“΄ 100% Local & Offline: No cloud telemetry, no subscription fees, no internet needed.

πŸ“– Command & CLI Reference

CommandWhat it does
branchbase initInteractively inspect repository and generate .branchbase.json
branchbase proxyStart the local transparent TCP routing proxy (default port: 5432)
branchbase statusDisplay the active Git branch, sanitized name, target DB, and driver status
branchbase listList 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 installInstall automated post-checkout and post-merge hooks into .git/hooks/
branchbase hooks statusInspect Git hooks installation and activity status
branchbase pruneDetect and delete databases associated with merged or deleted Git branches
branchbase versionPrint the current BranchBase version

πŸ“ Repository Structure

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

βš™οΈ How It Works (Step-by-Step)

  1. Detection: When you run git checkout <branch>, BranchBase's hook (.git/hooks/post-checkout) detects the branch transition in under 5ms by reading .git/HEAD.
  2. Identifier Sanitization: Special characters like / or - in branch names (e.g. feature/stripe-v2) are converted into safe database identifiers (feature_stripe_v2).
  3. Copy-on-Write Snapshot:
    • PostgreSQL: Disconnects lingering connections to the template and executes CREATE DATABASE <target> TEMPLATE <source>; (instant CoW clone).
    • SQLite: Issues PRAGMA wal_checkpoint(TRUNCATE); and performs a filesystem reflink/clone (clonefile() or FICLONE).
  4. Transparent Routing: When your backend app queries localhost:5432, the BranchBase proxy intercepts the connection, resolves the active branch database, and forwards traffic seamlessly.
  5. Lifecycle Pruning: Once a PR is merged into main, running branchbase prune removes the ephemeral database, freeing disk space.

🧩 Extension Model: Adding a New Database Driver

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)
}
  1. Create internal/driver/<engine>/<engine>.go.
  2. Implement the Driver interface.
  3. Register your factory via driver.Register("<engine>", factory) in init().
  4. See our dedicated Driver Development Skill for full instructions.

πŸ› οΈ Quickstart

1. Initialize in your Repository

cd my-awesome-project
branchbase init

2. Start the Transparent Proxy

branchbase proxy

3. Work with Git as you always do!

# 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!

🀝 Contributing & Community

Thinking about contributing? We'd love to have you!

  • New Contributors: Check our good first issue label for onboarding tasks.
  • Contributor Guide: Read CONTRIBUTING.md for coding standards, Conventional Commits, and PR rules.
  • Environment Setup: See SETUP.md for local Go and Docker development steps.
  • Code of Conduct: All interactions are governed by our Code of Conduct.

πŸ›‘οΈ Security

To report a vulnerability privately, please see SECURITY.md or use GitHub Private Vulnerability Reporting.


πŸ’– Support & Sponsorship

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!


πŸ“„ License

Licensed under the MIT License.

Contributors

oscarbol09

5 commits

oscarbol09/branchbase

Zero-config, Git-native local database branching for PostgreSQL, MySQL, and SQLite.

3

stars

8

commits

Go

primary language

Sep 6, 2026

updated

branching
database
developer-tools
devops
docker
git
golang
postgres
sqlite

README

BranchBase 🌿

Zero-config, Git-native local database branching for PostgreSQL, MySQL, and SQLite.
Stop dropping your local database every time you switch Git branches.

BranchBase CI Go Version License: MIT PRs Welcome Good First Issues GitHub Sponsors Support on Ko-Fi


⚑ The Problem: The "Git vs. Local Database" Friction

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".

How developers waste hours today:

  • The Nuclear Option: docker compose down -v && docker compose up -d
    (Loses all your test seeds, logins, and mocked state. Takes minutes to re-seed).
  • The Manual Rollback Dance: Trying to rollback migrations on feature/checkout-v2 before switching, only to lose experimental test data.
  • The .env Nightmare: Manually maintaining DATABASE_URL_DEV, DATABASE_URL_CHECKOUT, and editing .env on every branch change.
  • Cloud Branching (Neon, PlanetScale): Great developer experience, but proprietary, paid, and requires an internet connection. It doesn't work for offline development or standard local Docker setups.

πŸš€ The Solution: BranchBase

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) |
+---------------------------------------+   +------------------------------------+

Key Highlights

  • ⚑ Instant Branching: Creates a fresh, isolated branch database in milliseconds using PostgreSQL CREATE DATABASE ... TEMPLATE or filesystem copy-on-write (reflink/APFS/Btrfs for SQLite).
  • πŸ”Œ Transparent Connection Proxy: Your app's 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.
  • 🎣 Automated Git Hook: Hooks into post-checkout and post-merge. You simply use standard git checkout or git switch.
  • 🧹 Automatic Cleanup (prune): When you delete or merge a Git branch, branchbase safely tears down the associated ephemeral database.
  • πŸ“΄ 100% Local & Offline: No cloud telemetry, no subscription fees, no internet needed.

πŸ“– Command & CLI Reference

CommandWhat it does
branchbase initInteractively inspect repository and generate .branchbase.json
branchbase proxyStart the local transparent TCP routing proxy (default port: 5432)
branchbase statusDisplay the active Git branch, sanitized name, target DB, and driver status
branchbase listList 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 installInstall automated post-checkout and post-merge hooks into .git/hooks/
branchbase hooks statusInspect Git hooks installation and activity status
branchbase pruneDetect and delete databases associated with merged or deleted Git branches
branchbase versionPrint the current BranchBase version

πŸ“ Repository Structure

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

βš™οΈ How It Works (Step-by-Step)

  1. Detection: When you run git checkout <branch>, BranchBase's hook (.git/hooks/post-checkout) detects the branch transition in under 5ms by reading .git/HEAD.
  2. Identifier Sanitization: Special characters like / or - in branch names (e.g. feature/stripe-v2) are converted into safe database identifiers (feature_stripe_v2).
  3. Copy-on-Write Snapshot:
    • PostgreSQL: Disconnects lingering connections to the template and executes CREATE DATABASE <target> TEMPLATE <source>; (instant CoW clone).
    • SQLite: Issues PRAGMA wal_checkpoint(TRUNCATE); and performs a filesystem reflink/clone (clonefile() or FICLONE).
  4. Transparent Routing: When your backend app queries localhost:5432, the BranchBase proxy intercepts the connection, resolves the active branch database, and forwards traffic seamlessly.
  5. Lifecycle Pruning: Once a PR is merged into main, running branchbase prune removes the ephemeral database, freeing disk space.

🧩 Extension Model: Adding a New Database Driver

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)
}
  1. Create internal/driver/<engine>/<engine>.go.
  2. Implement the Driver interface.
  3. Register your factory via driver.Register("<engine>", factory) in init().
  4. See our dedicated Driver Development Skill for full instructions.

πŸ› οΈ Quickstart

1. Initialize in your Repository

cd my-awesome-project
branchbase init

2. Start the Transparent Proxy

branchbase proxy

3. Work with Git as you always do!

# 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!

🀝 Contributing & Community

Thinking about contributing? We'd love to have you!

  • New Contributors: Check our good first issue label for onboarding tasks.
  • Contributor Guide: Read CONTRIBUTING.md for coding standards, Conventional Commits, and PR rules.
  • Environment Setup: See SETUP.md for local Go and Docker development steps.
  • Code of Conduct: All interactions are governed by our Code of Conduct.

πŸ›‘οΈ Security

To report a vulnerability privately, please see SECURITY.md or use GitHub Private Vulnerability Reporting.


πŸ’– Support & Sponsorship

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!


πŸ“„ License

Licensed under the MIT License.

Contributors

oscarbol09

5 commits

Languages

Go

100.0%