Merge branch 'main' of github.com:steveyegge/beads

# Conflicts:
#	.beads/beads.jsonl
This commit is contained in:
Steve Yegge
2025-11-06 19:07:31 -08:00
4 changed files with 164 additions and 165 deletions

File diff suppressed because one or more lines are too long

View File

@@ -69,18 +69,20 @@ The hook is silent on success, fast (no git operations), and safe (fails commit
### pre-push ### pre-push
Before each push, the hook checks: Before each push, the hook:
```bash ```bash
git diff --quiet .beads/beads.jsonl bd sync --flush-only # Flush pending changes (if bd available)
git status --porcelain .beads/*.jsonl # Check for uncommitted changes
``` ```
This prevents pushing stale JSONL by: This prevents pushing stale JSONL by:
1. Checking if JSONL has uncommitted changes (working tree or staging) 1. Flushing pending in-memory changes from daemon's 5s debounce
2. Failing the push with clear error message if changes exist 2. Checking for uncommitted changes (staged, unstaged, untracked, deleted)
3. Instructing user to commit JSONL before pushing again 3. Failing the push with clear error message if changes exist
4. Instructing user to commit JSONL before pushing again
This solves bd-my64: changes made between commit and push are caught before reaching remote. This solves bd-my64: changes made between commit and push (or pending debounced flushes) are caught before reaching remote.
### post-merge ### post-merge

View File

@@ -35,17 +35,10 @@ if ! bd sync --flush-only >/dev/null 2>&1; then
exit 1 exit 1
fi fi
# Find the JSONL file (could be issues.jsonl or beads.jsonl) # Stage both possible JSONL files (backward compatibility)
JSONL_FILE="" # git add is harmless if file doesn't exist
if [ -f .beads/beads.jsonl ]; then for f in .beads/beads.jsonl .beads/issues.jsonl; do
JSONL_FILE=".beads/beads.jsonl" [ -f "$f" ] && git add "$f" 2>/dev/null || true
elif [ -f .beads/issues.jsonl ]; then done
JSONL_FILE=".beads/issues.jsonl"
fi
# If the JSONL file was modified, stage it
if [ -n "$JSONL_FILE" ] && [ -f "$JSONL_FILE" ]; then
git add "$JSONL_FILE" 2>/dev/null || true
fi
exit 0 exit 0

View File

@@ -3,11 +3,14 @@
# #
# bd (beads) pre-push hook # bd (beads) pre-push hook
# #
# This hook checks if the database has uncommitted changes and prevents # This hook prevents pushing stale JSONL by:
# pushing stale JSONL by failing with a clear error message. # 1. Flushing any pending in-memory changes to JSONL (if bd available)
# 2. Checking for uncommitted changes (staged, unstaged, untracked, deleted)
# 3. Failing the push with clear instructions if changes found
# #
# The pre-commit hook should have already exported changes, but if new # The pre-commit hook already exports changes, but this catches:
# changes were made between commit and push, this hook catches that. # - Changes made between commit and push
# - Pending debounced flushes (5s daemon delay)
# #
# Installation: # Installation:
# cp examples/git-hooks/pre-push .git/hooks/pre-push # cp examples/git-hooks/pre-push .git/hooks/pre-push
@@ -16,37 +19,40 @@
# Or use the install script: # Or use the install script:
# examples/git-hooks/install.sh # examples/git-hooks/install.sh
# Check if bd is available
if ! command -v bd >/dev/null 2>&1; then
# If bd is not available, we can't check - allow push
exit 0
fi
# Check if we're in a bd workspace # Check if we're in a bd workspace
if [ ! -d .beads ]; then if [ ! -d .beads ]; then
# Not a bd workspace, nothing to do # Not a bd workspace, nothing to do
exit 0 exit 0
fi fi
# Find the JSONL file (could be issues.jsonl or beads.jsonl) # Optionally flush pending bd changes so they surface in JSONL
JSONL_FILE="" # This prevents the race where a debounced flush lands after the check
if [ -f .beads/beads.jsonl ]; then if command -v bd >/dev/null 2>&1; then
JSONL_FILE=".beads/beads.jsonl" bd sync --flush-only >/dev/null 2>&1 || true
elif [ -f .beads/issues.jsonl ]; then
JSONL_FILE=".beads/issues.jsonl"
fi fi
# Check if JSONL file has uncommitted changes # Collect all tracked or existing JSONL files (supports both old and new names)
if [ -n "$JSONL_FILE" ] && [ -f "$JSONL_FILE" ]; then FILES=""
# Check git status for the JSONL file for f in .beads/beads.jsonl .beads/issues.jsonl; do
if ! git diff --quiet "$JSONL_FILE" 2>/dev/null || ! git diff --cached --quiet "$JSONL_FILE" 2>/dev/null; then # Include file if it exists in working tree OR is tracked by git (even if deleted)
echo "❌ Error: $JSONL_FILE has uncommitted changes" >&2 if git ls-files --error-unmatch "$f" >/dev/null 2>&1 || [ -f "$f" ]; then
FILES="$FILES $f"
fi
done
# Check for any uncommitted changes using porcelain status
# This catches: staged, unstaged, untracked, deleted, renamed, and conflicts
if [ -n "$FILES" ]; then
# shellcheck disable=SC2086
if [ -n "$(git status --porcelain -- $FILES 2>/dev/null)" ]; then
echo "❌ Error: Beads JSONL has uncommitted changes" >&2
echo "" >&2 echo "" >&2
echo "You made changes to bd issues between your last commit and this push." >&2 echo "You made changes to bd issues between your last commit and this push." >&2
echo "Please commit the updated JSONL file before pushing:" >&2 echo "Please commit the updated JSONL before pushing:" >&2
echo "" >&2 echo "" >&2
echo " git add $JSONL_FILE" >&2 # shellcheck disable=SC2086
echo " git commit -m \"Update beads JSONL\"" >&2 echo " git add $FILES" >&2
echo ' git commit -m "Update bd JSONL"' >&2
echo " git push" >&2 echo " git push" >&2
echo "" >&2 echo "" >&2
exit 1 exit 1