Automatic export/import of beads issues during git operations.
- pre-commit: Exports SQLite → JSONL before every commit
- post-merge: Imports JSONL → SQLite after git pull/merge
- post-checkout: Imports JSONL → SQLite after branch switching
This keeps your .beads/issues.jsonl (committed to git) in sync with your local SQLite database (gitignored).
cd /path/to/your/project
./examples/git-hooks/install.shThe installer will prompt before overwriting existing hooks.
# Copy hooks to .git/hooks/
cp examples/git-hooks/pre-commit .git/hooks/
cp examples/git-hooks/post-merge .git/hooks/
cp examples/git-hooks/post-checkout .git/hooks/
# Make them executable
chmod +x .git/hooks/pre-commit
chmod +x .git/hooks/post-merge
chmod +x .git/hooks/post-checkoutOnce installed, the hooks run automatically:
# Creating/updating issues
bd create "New feature" -p 1
bd update bd-1 --status in_progress
# Committing changes - hook exports automatically
git add .
git commit -m "Update feature"
# 🔗 Exporting beads issues to JSONL...
# ✓ Beads issues exported and staged
# Pulling changes - hook imports automatically
git pull
# 🔗 Importing beads issues from JSONL...
# ✓ Beads issues imported successfully
# Switching branches - hook imports automatically
git checkout feature-branch
# 🔗 Importing beads issues from JSONL...
# ✓ Beads issues imported successfully- You work with bd commands (
create,update,close) - Changes are stored in SQLite (
.beads/*.db) - fast local queries - Before commit, hook exports to JSONL (
.beads/issues.jsonl) - git-friendly - JSONL is committed to git (source of truth)
- After pull/merge/checkout, hook imports JSONL back to SQLite
- Your local SQLite cache is now in sync with git
SQLite for speed:
- Fast queries (dependency trees, ready work)
- Rich SQL capabilities
- Sub-100ms response times
JSONL for git:
- Clean diffs (one issue per line)
- Mergeable (independent lines)
- Human-readable
- AI-resolvable conflicts
Best of both worlds!
# Check if hook is executable
ls -l .git/hooks/pre-commit
# Should show -rwxr-xr-x
# Make it executable if needed
chmod +x .git/hooks/pre-commit# Check if bd is in PATH
which bd
# Check if you're in a beads-initialized directory
bd listIf you get merge conflicts in .beads/issues.jsonl:
- Most conflicts are safe to resolve by keeping both sides
- Each line is an independent issue
- Look for
<<<<<<< HEADmarkers - Keep all lines that don't conflict
- For actual conflicts on the same issue, choose the newest
Example conflict:
<<<<<<< HEAD
{"id":"bd-3","title":"Updated title","status":"closed","updated_at":"2025-10-12T10:00:00Z"}
=======
{"id":"bd-3","title":"Updated title","status":"in_progress","updated_at":"2025-10-12T09:00:00Z"}
>>>>>>> feature-branch
Resolution: Keep the HEAD version (newer timestamp).
After resolving:
git add .beads/issues.jsonl
git commit
bd import -i .beads/issues.jsonl # Sync to SQLiterm .git/hooks/pre-commit
rm .git/hooks/post-merge
rm .git/hooks/post-checkoutgit commit --no-verify -m "Skip hooks"If you already have git hooks, you can append to them:
# Append to existing pre-commit
cat examples/git-hooks/pre-commit >> .git/hooks/pre-commitExport only specific issues:
# Edit pre-commit hook, change:
bd export --format=jsonl -o .beads/issues.jsonl
# To:
bd export --format=jsonl --status=open -o .beads/issues.jsonl- Git hooks documentation
- ../../TEXT_FORMATS.md - JSONL merge strategies
- ../../GIT_WORKFLOW.md - Design rationale