Files
beads/examples/git-hooks/README.md
Steve Yegge 3ba245e6c0 Fix bd-my64: Pre-push hook blocks instead of exports
The original pre-push hook tried to export DB → JSONL during the push,
then run 'git add', but this doesn't work because:

1. The commit is already created when pre-push runs
2. git add in pre-push stages files for a FUTURE commit
3. The current push sends the old commit with stale JSONL
4. Result: dirty git status after push

Fix:
- Pre-push now CHECKS for uncommitted JSONL changes
- If found, it FAILS the push with clear instructions
- User must commit JSONL before pushing
- This prevents stale JSONL from reaching remote

The pre-commit hook already properly flushes changes, so this
catch-all prevents changes made BETWEEN commit and push.

Amp-Thread-ID: https://ampcode.com/threads/T-39a89553-c301-4d4f-b39f-6df9c403d22b
Co-authored-by: Amp <amp@ampcode.com>
2025-11-06 18:57:34 -08:00

129 lines
3.6 KiB
Markdown

# bd Git Hooks
This directory contains git hooks that integrate bd (beads) with your git workflow, preventing stale JSONL from being pushed to remote.
## The Problem
Two race conditions can occur:
1. **Between operations and commits**: Daemon auto-flush (5s debounce) may fire after commit
- User closes issue via MCP → daemon schedules flush (5 sec delay)
- User commits code changes → JSONL appears clean
- Daemon flush fires → JSONL modified after commit
- Result: dirty working tree showing JSONL changes
2. **Between commits and pushes**: Changes made after commit but before push (bd-my64)
- User commits → pre-commit hook flushes JSONL
- User adds comments or updates issues
- User pushes → outdated JSONL is pushed
- Result: remote has stale JSONL
## The Solution
These git hooks ensure bd changes are always synchronized with your commits and pushes:
- **pre-commit** - Flushes pending bd changes to JSONL before commit and stages it
- **pre-push** - Blocks push if JSONL has uncommitted changes (bd-my64)
- **post-merge** - Imports updated JSONL after git pull/merge
## Installation
### Quick Install
From your repository root:
```bash
./examples/git-hooks/install.sh
```
This will:
- Copy hooks to `.git/hooks/`
- Make them executable
- Back up any existing hooks
### Manual Install
```bash
cp examples/git-hooks/pre-commit .git/hooks/pre-commit
cp examples/git-hooks/pre-push .git/hooks/pre-push
cp examples/git-hooks/post-merge .git/hooks/post-merge
chmod +x .git/hooks/pre-commit .git/hooks/pre-push .git/hooks/post-merge
```
## How It Works
### pre-commit
Before each commit, the hook runs:
```bash
bd sync --flush-only
```
This:
1. Exports any pending database changes to `.beads/issues.jsonl`
2. Stages the JSONL file if modified
3. Allows the commit to proceed with clean state
The hook is silent on success, fast (no git operations), and safe (fails commit if flush fails).
### pre-push
Before each push, the hook checks:
```bash
git diff --quiet .beads/beads.jsonl
```
This prevents pushing stale JSONL by:
1. Checking if JSONL has uncommitted changes (working tree or staging)
2. Failing the push with clear error message if changes exist
3. Instructing user to commit JSONL before pushing again
This solves bd-my64: changes made between commit and push are caught before reaching remote.
### post-merge
After a git pull or merge, the hook runs:
```bash
bd import -i .beads/beads.jsonl
```
This ensures your local database reflects the merged state. The hook:
- Only runs if `.beads/beads.jsonl` exists (also checks `issues.jsonl` for backward compat)
- Imports any new issues or updates from the merge
- Warns on failure but doesn't block the merge
**Note:** With hash-based IDs (v0.20.1+), ID collisions don't occur - different issues get different hash IDs.
## Compatibility
- **Auto-sync**: Works alongside bd's automatic 5-second debounce
- **Direct mode**: Hooks work in both daemon and `--no-daemon` mode
- **Worktrees**: Safe to use with git worktrees
## Benefits
✅ No more dirty working tree after commits
✅ Database always in sync with git
✅ Automatic collision resolution on merge
✅ Fast and silent operation
✅ Optional - manual `bd sync` still works
## Uninstall
Remove the hooks:
```bash
rm .git/hooks/pre-commit .git/hooks/pre-push .git/hooks/post-merge
```
Your backed-up hooks (if any) are in `.git/hooks/*.backup-*`.
## Related
- See [bd-51](../../.beads/bd-51) for the race condition bug report
- See [AGENTS.md](../../AGENTS.md) for the full git workflow
- See [examples/](../) for other integrations