Skip to content

Git Hooks

pgbranch can install a git hook that automatically switches database branches when you switch git branches.

When you switch git branches with git checkout or git switch, the post-checkout hook runs pgbranch checkout <branch-name>.

git checkout feature-auth
post-checkout hook
pgbranch checkout feature-auth
Database now matches git branch

If a matching pgbranch branch doesn’t exist, the hook silently continues without error.

Terminal window
pgbranch hook install

Output:

Git hook installed successfully!
Database branches will now switch automatically with git branches.

This creates a post-checkout script in .git/hooks/.

Terminal window
pgbranch hook uninstall

Output:

Git hook removed.

The installed hook script:

#!/bin/sh
# pgbranch post-checkout hook
# Get the new branch name
BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)
# Skip if not on a branch (e.g., detached HEAD)
if [ -z "$BRANCH" ]; then
exit 0
fi
# Try to checkout the matching pgbranch branch
pgbranch checkout "$BRANCH" 2>/dev/null || true

Key behaviors:

  • Runs after every git checkout
  • Silently fails if no matching branch exists
  • Doesn’t block git operations on error

For automatic switching to work well, use matching names:

Terminal window
# Git branch
git checkout -b feature-user-auth
# pgbranch branch (same name)
pgbranch branch feature-user-auth
Git Branchpgbranch Branch
mainmain
developdevelop
feature/user-authfeature-user-auth
feature/api-v2feature-api-v2
Terminal window
# Initialize pgbranch
pgbranch init -d myapp_dev
# Create main branch from clean state
git checkout main
pgbranch branch main
# Install the hook
pgbranch hook install
Terminal window
# Start feature work
git checkout -b feature-new-api
# (hook runs, but no pgbranch branch exists yet)
# Create database branch
pgbranch branch feature-new-api
# Work on feature, make changes...
# Switch to fix a bug on main
git checkout main
# Hook automatically runs: pgbranch checkout main
# Database is now in main state!
# Back to feature
git checkout feature-new-api
# Hook automatically runs: pgbranch checkout feature-new-api
# Database restored to feature state!

When the hook tries to checkout a non-existent branch:

Terminal window
git checkout feature-new
# Hook: pgbranch checkout feature-new
# pgbranch: branch 'feature-new' doesn't exist (silent)
# Git checkout completes normally

Your git checkout succeeds, and the database stays on the previous branch.

You can modify the hook to create branches automatically:

#!/bin/sh
BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)
if [ -z "$BRANCH" ]; then
exit 0
fi
# Try checkout, or create if doesn't exist
if ! pgbranch checkout "$BRANCH" 2>/dev/null; then
pgbranch branch "$BRANCH" 2>/dev/null || true
fi

If you already have a post-checkout hook:

Terminal window
pgbranch hook install

Output:

Warning: post-checkout hook already exists
Do you want to:
1. Append pgbranch to existing hook
2. Replace existing hook
3. Cancel
Choice [1/2/3]:

Choose option 1 to keep both hooks working.

The hook is installed at:

.git/hooks/post-checkout

You can edit it manually if needed.

To skip the hook for one checkout:

Terminal window
git checkout --no-verify main

Or temporarily uninstall:

Terminal window
pgbranch hook uninstall
git checkout main
pgbranch hook install

The hook adds a small delay to git checkouts:

  • Fast (no matching branch): ~50ms
  • With branch switch: 1-5 seconds (depends on DB size)

For large databases, consider disabling the hook and switching manually when needed.

Check if the hook is executable:

Terminal window
ls -la .git/hooks/post-checkout
# Should show: -rwxr-xr-x

Make executable if needed:

Terminal window
chmod +x .git/hooks/post-checkout

If the database doesn’t match after git checkout:

  1. Check if pgbranch branch exists:

    Terminal window
    pgbranch branch
  2. Manually checkout:

    Terminal window
    pgbranch checkout <branch-name>

If the hook shows errors, check:

  1. pgbranch is in PATH
  2. pgbranch is initialized in the directory
  3. Database is accessible

In CI/CD environments, you typically don’t want the hook:

Terminal window
# Clone without hooks
git clone --no-checkout repo.git
cd repo
git checkout main

Or disable hooks:

Terminal window
git config core.hooksPath /dev/null