When bd sync pushes from the sync-branch worktree, the pre-push hook
would detect uncommitted JSONL changes and suggest running bd sync -
which is circular since that's what the user is already doing.
Fix: Set BD_SYNC_IN_PROGRESS=1 environment variable when pushing from
worktree, and update pre-push hook to skip checks when this var is set.
Updated files:
- internal/syncbranch/worktree.go: Set env var on push command
- cmd/bd/templates/hooks/pre-push: Check for env var and exit early
- examples/git-hooks/pre-push: Same check
- .beads-hooks/pre-push: Same check
- Change comments from sync.branch to sync-branch for consistency
- Add head -1 to handle malformed YAML with duplicate keys
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previously sync.branch was stored in the database via bd config set.
Now it is in config.yaml (version controlled, shared across clones):
sync-branch: "beads-sync"
Changes:
- Add sync-branch to .beads/config.yaml
- Update syncbranch.Get() to check config.yaml before database
- Add syncbranch.GetFromYAML() and IsConfigured() for fast checks
- Update hooks to read sync-branch from config.yaml directly
- Update bd doctor to check config.yaml instead of database
- Remove auto-fix (config.yaml changes should be committed)
Precedence: BEADS_SYNC_BRANCH env > config.yaml > database (legacy)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
When sync.branch is configured, .beads changes are committed to a
separate branch via worktree rather than the current branch. Updated
both hooks to detect this configuration and skip the uncommitted
.beads check in that scenario.
Changes:
- pre-push: Skip uncommitted .beads check when sync.branch is set
- pre-commit: Skip flush and auto-staging when sync.branch is set
- Both: Use --json output for reliable config value detection
- Bump version to 0.22.2
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The pre-commit and pre-push hooks were only staging beads.jsonl and
issues.jsonl, but not deletions.jsonl. This caused deletions.jsonl
to remain untracked after bd cleanup or bd delete operations.
Updated all hook locations:
- cmd/bd/templates/hooks/pre-commit
- cmd/bd/templates/hooks/pre-push
- examples/git-hooks/pre-commit
- examples/git-hooks/pre-push
- .beads-hooks/pre-commit
- .beads-hooks/pre-push
Users with existing hooks should run: bd hooks install
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The pre-push hook now provides better guidance when beads JSONL has
uncommitted changes:
- Interactive terminals: Prompts to auto-run 'bd sync' (y/N)
- Non-interactive/CI: Shows 'bd sync' command to run
- Fallback: Manual git commands if bd not available
This addresses the UX issue where users weren't sure they should
run 'bd sync' instead of manual git commands.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Oracle identified a critical race condition in the initial fix:
- Pre-push hook checked for changes but didn't flush first
- Pending 5s-debounced flushes could land after the check
- Result: stale JSONL could still be pushed
Improvements:
1. Pre-push now flushes pending changes FIRST (bd sync --flush-only)
2. Uses git status --porcelain to catch ALL change types:
- Staged, unstaged, untracked, deleted, renamed, conflicts
3. Handles both beads.jsonl and issues.jsonl (backward compat)
4. Works even without bd installed (git-only check)
5. Pre-commit stages both JSONL files (simpler loop)
This completely eliminates the race condition.
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>