Add comprehensive protected branch workflow documentation (bd-5ce8)
Created complete documentation suite for using beads with protected branches: 1. **docs/PROTECTED_BRANCHES.md** - Comprehensive 600+ line guide covering: - Quick start and setup - How git worktrees work - Daily workflow for agents and humans - Merging strategies (PR and direct) - Troubleshooting common issues - Platform-specific notes (GitHub, GitLab, Bitbucket) - Advanced topics (CI/CD, multi-clone sync, etc.) 2. **AGENTS.md** - Added "Protected Branch Workflow" section: - Quick reference for agents - No changes needed to agent workflows - Commands for setup and merging - Link to detailed docs 3. **README.md** - Updated with: - Protected branch support feature flag - Quick start instructions with --branch flag - Link to comprehensive guide 4. **examples/protected-branch/** - Working example with: - Step-by-step demo - Multi-clone sync workflow - GitHub Actions integration example - Directory structure explanation - Troubleshooting tips All commands verified: - bd init --branch <name> - bd config get/set sync.branch - bd sync --status - bd sync --merge Documentation is platform-agnostic and works with GitHub, GitLab, Bitbucket, or any git platform with branch protection. Closes bd-5ce8 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
51
AGENTS.md
51
AGENTS.md
@@ -508,6 +508,57 @@ beads/
|
|||||||
|
|
||||||
The 30-second debounce provides a **transaction window** for batch operations - multiple issue changes within 30 seconds get flushed together, avoiding commit spam.
|
The 30-second debounce provides a **transaction window** for batch operations - multiple issue changes within 30 seconds get flushed together, avoiding commit spam.
|
||||||
|
|
||||||
|
### Protected Branch Workflow
|
||||||
|
|
||||||
|
**If your repository uses protected branches (GitHub, GitLab, etc.)**, beads can commit to a separate branch instead of `main`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Initialize with separate sync branch
|
||||||
|
bd init --branch beads-metadata
|
||||||
|
|
||||||
|
# Or configure existing setup
|
||||||
|
bd config set sync.branch beads-metadata
|
||||||
|
```
|
||||||
|
|
||||||
|
**How it works:**
|
||||||
|
- Beads commits issue updates to `beads-metadata` instead of `main`
|
||||||
|
- Uses git worktrees (lightweight checkouts) in `.git/beads-worktrees/`
|
||||||
|
- Your main working directory is never affected
|
||||||
|
- Periodically merge `beads-metadata` back to `main` via pull request
|
||||||
|
|
||||||
|
**Daily workflow (unchanged for agents):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Agents work normally - no changes needed!
|
||||||
|
bd create "Fix authentication" -t bug -p 1
|
||||||
|
bd update bd-a1b2 --status in_progress
|
||||||
|
bd close bd-a1b2 "Fixed"
|
||||||
|
```
|
||||||
|
|
||||||
|
All changes automatically commit to `beads-metadata` branch (if daemon is running with `--auto-commit`).
|
||||||
|
|
||||||
|
**Merging to main (humans):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check what's changed
|
||||||
|
bd sync --status
|
||||||
|
|
||||||
|
# Option 1: Create pull request
|
||||||
|
git push origin beads-metadata
|
||||||
|
# Then create PR on GitHub/GitLab
|
||||||
|
|
||||||
|
# Option 2: Direct merge (if allowed)
|
||||||
|
bd sync --merge
|
||||||
|
```
|
||||||
|
|
||||||
|
**Benefits:**
|
||||||
|
- ✅ Works with protected `main` branches
|
||||||
|
- ✅ No disruption to agent workflows
|
||||||
|
- ✅ Platform-agnostic (works on any git platform)
|
||||||
|
- ✅ Backward compatible (opt-in via config)
|
||||||
|
|
||||||
|
**See [docs/PROTECTED_BRANCHES.md](docs/PROTECTED_BRANCHES.md) for complete setup guide, troubleshooting, and examples.**
|
||||||
|
|
||||||
### Agent Session Workflow
|
### Agent Session Workflow
|
||||||
|
|
||||||
**IMPORTANT for AI agents:** When you finish making issue changes, always run:
|
**IMPORTANT for AI agents:** When you finish making issue changes, always run:
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ Agents report that they enjoy working with Beads, and they will use it spontaneo
|
|||||||
- 🤖 **Agent-friendly** - `--json` flags for programmatic integration
|
- 🤖 **Agent-friendly** - `--json` flags for programmatic integration
|
||||||
- 📦 **Git-versioned** - JSONL records stored in git, synced across machines
|
- 📦 **Git-versioned** - JSONL records stored in git, synced across machines
|
||||||
- 🌍 **Distributed by design** - Agents on multiple machines share one logical database via git
|
- 🌍 **Distributed by design** - Agents on multiple machines share one logical database via git
|
||||||
|
- 🔐 **Protected branch support** - Works with GitHub/GitLab protected branches via separate sync branch
|
||||||
- 🏗️ **Extensible** - Add your own tables to the SQLite database
|
- 🏗️ **Extensible** - Add your own tables to the SQLite database
|
||||||
- 🔍 **Multi-project isolation** - Each project gets its own database, auto-discovered by directory
|
- 🔍 **Multi-project isolation** - Each project gets its own database, auto-discovered by directory
|
||||||
- 🌲 **Dependency trees** - Visualize full dependency graphs
|
- 🌲 **Dependency trees** - Visualize full dependency graphs
|
||||||
@@ -93,6 +94,9 @@ Beads is designed for **AI coding agents** to use on your behalf. Setup takes 30
|
|||||||
# In your project root:
|
# In your project root:
|
||||||
bd init
|
bd init
|
||||||
|
|
||||||
|
# For protected branches (GitHub/GitLab):
|
||||||
|
bd init --branch beads-metadata
|
||||||
|
|
||||||
# bd will:
|
# bd will:
|
||||||
# - Create .beads/ directory with database
|
# - Create .beads/ directory with database
|
||||||
# - Import existing issues from git (if any)
|
# - Import existing issues from git (if any)
|
||||||
@@ -103,6 +107,8 @@ bd init
|
|||||||
echo "BEFORE ANYTHING ELSE: run 'bd onboard' and follow the instructions" >> AGENTS.md
|
echo "BEFORE ANYTHING ELSE: run 'bd onboard' and follow the instructions" >> AGENTS.md
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Protected branches?** If your `main` branch is protected, use `bd init --branch beads-metadata` to commit issue updates to a separate branch. See [docs/PROTECTED_BRANCHES.md](docs/PROTECTED_BRANCHES.md) for details.
|
||||||
|
|
||||||
**Your agent does the rest:** Next time your agent starts, it will:
|
**Your agent does the rest:** Next time your agent starts, it will:
|
||||||
1. Run `bd onboard` and receive integration instructions
|
1. Run `bd onboard` and receive integration instructions
|
||||||
2. Add bd workflow documentation to AGENTS.md
|
2. Add bd workflow documentation to AGENTS.md
|
||||||
|
|||||||
658
docs/PROTECTED_BRANCHES.md
Normal file
658
docs/PROTECTED_BRANCHES.md
Normal file
@@ -0,0 +1,658 @@
|
|||||||
|
# Protected Branch Workflow
|
||||||
|
|
||||||
|
This guide explains how to use beads with protected branches on platforms like GitHub, GitLab, and Bitbucket.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Overview](#overview)
|
||||||
|
- [Quick Start](#quick-start)
|
||||||
|
- [How It Works](#how-it-works)
|
||||||
|
- [Setup](#setup)
|
||||||
|
- [Daily Workflow](#daily-workflow)
|
||||||
|
- [Merging Changes](#merging-changes)
|
||||||
|
- [Troubleshooting](#troubleshooting)
|
||||||
|
- [FAQ](#faq)
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
**Problem:** GitHub and other platforms let you protect branches (like `main`) to require pull requests for all changes. This prevents beads from auto-committing issue updates directly to `main`.
|
||||||
|
|
||||||
|
**Solution:** Beads can commit to a separate branch (like `beads-metadata`) using git worktrees, while keeping your main working directory untouched. Periodically merge the metadata branch back to `main` via a pull request.
|
||||||
|
|
||||||
|
**Benefits:**
|
||||||
|
- ✅ Works with any git platform's branch protection
|
||||||
|
- ✅ Main branch stays protected
|
||||||
|
- ✅ No disruption to your primary working directory
|
||||||
|
- ✅ Backward compatible (opt-in via config)
|
||||||
|
- ✅ Minimal disk overhead (uses sparse checkout)
|
||||||
|
- ✅ Platform-agnostic solution
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
**1. Initialize beads with a separate sync branch:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd your-project
|
||||||
|
bd init --branch beads-metadata
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates a `.beads/` directory and configures beads to commit to `beads-metadata` instead of `main`.
|
||||||
|
|
||||||
|
**2. Start the daemon with auto-commit:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bd daemon start --auto-commit
|
||||||
|
```
|
||||||
|
|
||||||
|
The daemon will automatically commit issue changes to the `beads-metadata` branch.
|
||||||
|
|
||||||
|
**3. When ready, merge to main:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check what's changed
|
||||||
|
bd sync --status
|
||||||
|
|
||||||
|
# Merge to main (creates a pull request or direct merge)
|
||||||
|
bd sync --merge
|
||||||
|
```
|
||||||
|
|
||||||
|
That's it! The complete workflow is described below.
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
### Git Worktrees
|
||||||
|
|
||||||
|
Beads uses [git worktrees](https://git-scm.com/docs/git-worktree) to maintain a lightweight checkout of your sync branch. Think of it as a mini git clone that shares the same repository history.
|
||||||
|
|
||||||
|
**Directory structure:**
|
||||||
|
|
||||||
|
```
|
||||||
|
your-project/
|
||||||
|
├── .git/ # Main git directory
|
||||||
|
│ └── beads-worktrees/
|
||||||
|
│ └── beads-metadata/ # Worktree (only .beads/ checked out)
|
||||||
|
│ └── .beads/
|
||||||
|
│ └── beads.jsonl
|
||||||
|
├── .beads/ # Your main copy
|
||||||
|
│ ├── beads.db
|
||||||
|
│ └── beads.jsonl
|
||||||
|
└── src/ # Your code (untouched)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key points:**
|
||||||
|
- The worktree is in `.git/beads-worktrees/` (hidden from your workspace)
|
||||||
|
- Only `.beads/` is checked out in the worktree (sparse checkout)
|
||||||
|
- Changes to issues are committed in the worktree
|
||||||
|
- Your main working directory is never affected
|
||||||
|
- Disk overhead is minimal (~few MB for the worktree)
|
||||||
|
|
||||||
|
### Automatic Sync
|
||||||
|
|
||||||
|
When you update an issue:
|
||||||
|
|
||||||
|
1. Issue is updated in `.beads/beads.db` (SQLite database)
|
||||||
|
2. Daemon exports to `.beads/beads.jsonl` (JSONL file)
|
||||||
|
3. JSONL is copied to worktree (`.git/beads-worktrees/beads-metadata/.beads/`)
|
||||||
|
4. Daemon commits the change in the worktree to `beads-metadata` branch
|
||||||
|
5. Main branch stays untouched (no commits on `main`)
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
### Option 1: Initialize New Project
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd your-project
|
||||||
|
bd init --branch beads-metadata
|
||||||
|
```
|
||||||
|
|
||||||
|
This will:
|
||||||
|
- Create `.beads/` directory with database
|
||||||
|
- Set `sync.branch` config to `beads-metadata`
|
||||||
|
- Import any existing issues from git (if present)
|
||||||
|
- Prompt to install git hooks (recommended: say yes)
|
||||||
|
|
||||||
|
### Option 2: Migrate Existing Project
|
||||||
|
|
||||||
|
If you already have beads set up and want to switch to a separate branch:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Set the sync branch
|
||||||
|
bd config set sync.branch beads-metadata
|
||||||
|
|
||||||
|
# Start the daemon (it will create the worktree automatically)
|
||||||
|
bd daemon start --auto-commit
|
||||||
|
```
|
||||||
|
|
||||||
|
### Daemon Configuration
|
||||||
|
|
||||||
|
For automatic commits to the sync branch:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start daemon with auto-commit
|
||||||
|
bd daemon start --auto-commit
|
||||||
|
|
||||||
|
# Or with auto-commit and auto-push
|
||||||
|
bd daemon start --auto-commit --auto-push
|
||||||
|
```
|
||||||
|
|
||||||
|
**Daemon modes:**
|
||||||
|
- `--auto-commit`: Commits to sync branch after each change
|
||||||
|
- `--auto-push`: Also pushes to remote after each commit
|
||||||
|
- Default interval: 5 seconds (check for changes every 5s)
|
||||||
|
|
||||||
|
**Recommended:** Use `--auto-commit` but not `--auto-push` if you want to review changes before pushing. Use `--auto-push` if you want fully hands-free sync.
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
You can also configure the sync branch via environment variable:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export BEADS_SYNC_BRANCH=beads-metadata
|
||||||
|
bd daemon start --auto-commit
|
||||||
|
```
|
||||||
|
|
||||||
|
This is useful for CI/CD or temporary overrides.
|
||||||
|
|
||||||
|
## Daily Workflow
|
||||||
|
|
||||||
|
### For AI Agents
|
||||||
|
|
||||||
|
AI agents work exactly the same way as before:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create issues
|
||||||
|
bd create "Implement user authentication" -t feature -p 1
|
||||||
|
|
||||||
|
# Update issues
|
||||||
|
bd update bd-a1b2 --status in_progress
|
||||||
|
|
||||||
|
# Close issues
|
||||||
|
bd close bd-a1b2 "Completed authentication"
|
||||||
|
```
|
||||||
|
|
||||||
|
All changes are automatically committed to the `beads-metadata` branch by the daemon. No changes are needed to agent workflows!
|
||||||
|
|
||||||
|
### For Humans
|
||||||
|
|
||||||
|
**Check status:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# See what's changed on the sync branch
|
||||||
|
bd sync --status
|
||||||
|
```
|
||||||
|
|
||||||
|
This shows the diff between `beads-metadata` and `main` (or your current branch).
|
||||||
|
|
||||||
|
**Manual commit (if not using daemon):**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bd sync --flush-only # Export to JSONL and commit to sync branch
|
||||||
|
```
|
||||||
|
|
||||||
|
**Pull changes from remote:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Pull updates from other collaborators
|
||||||
|
bd sync --no-push
|
||||||
|
```
|
||||||
|
|
||||||
|
This pulls changes from the remote sync branch and imports them to your local database.
|
||||||
|
|
||||||
|
## Merging Changes
|
||||||
|
|
||||||
|
### Option 1: Via Pull Request (Recommended)
|
||||||
|
|
||||||
|
For protected branches with required reviews:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Push your sync branch
|
||||||
|
git push origin beads-metadata
|
||||||
|
|
||||||
|
# 2. Create PR on GitHub/GitLab/etc.
|
||||||
|
# - Base: main
|
||||||
|
# - Compare: beads-metadata
|
||||||
|
|
||||||
|
# 3. After PR is merged, update your local main
|
||||||
|
git checkout main
|
||||||
|
git pull
|
||||||
|
bd import # Import the merged changes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 2: Direct Merge (If Allowed)
|
||||||
|
|
||||||
|
If you have push access to `main`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check what will be merged
|
||||||
|
bd sync --merge --dry-run
|
||||||
|
|
||||||
|
# Merge sync branch to main
|
||||||
|
bd sync --merge
|
||||||
|
|
||||||
|
# This will:
|
||||||
|
# - Switch to main branch
|
||||||
|
# - Merge beads-metadata with --no-ff (creates merge commit)
|
||||||
|
# - Push to remote
|
||||||
|
# - Import merged changes to database
|
||||||
|
```
|
||||||
|
|
||||||
|
**Safety checks:**
|
||||||
|
- ✅ Verifies you're not on the sync branch
|
||||||
|
- ✅ Checks for uncommitted changes in working tree
|
||||||
|
- ✅ Detects merge conflicts and provides resolution steps
|
||||||
|
- ✅ Uses `--no-ff` for clear history
|
||||||
|
|
||||||
|
### Merge Conflicts
|
||||||
|
|
||||||
|
If you encounter conflicts during merge:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# bd sync --merge will detect conflicts and show:
|
||||||
|
Error: Merge conflicts detected
|
||||||
|
Conflicting files:
|
||||||
|
.beads/beads.jsonl
|
||||||
|
|
||||||
|
To resolve:
|
||||||
|
1. Fix conflicts in .beads/beads.jsonl
|
||||||
|
2. git add .beads/beads.jsonl
|
||||||
|
3. git commit
|
||||||
|
4. bd import # Reimport to sync database
|
||||||
|
```
|
||||||
|
|
||||||
|
**Resolving JSONL conflicts:**
|
||||||
|
|
||||||
|
JSONL files are append-only and line-based, so conflicts are rare. When they occur:
|
||||||
|
|
||||||
|
1. Open `.beads/beads.jsonl` and look for conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`)
|
||||||
|
2. Both versions are usually valid - keep both lines
|
||||||
|
3. Remove the conflict markers
|
||||||
|
4. Save and commit
|
||||||
|
|
||||||
|
Example conflict resolution:
|
||||||
|
|
||||||
|
```jsonl
|
||||||
|
<<<<<<< HEAD
|
||||||
|
{"id":"bd-a1b2","title":"Feature A","status":"closed","updated_at":"2025-11-02T10:00:00Z"}
|
||||||
|
=======
|
||||||
|
{"id":"bd-a1b2","title":"Feature A","status":"in_progress","updated_at":"2025-11-02T09:00:00Z"}
|
||||||
|
>>>>>>> beads-metadata
|
||||||
|
```
|
||||||
|
|
||||||
|
**Resolution:** Keep the line with the newer `updated_at`:
|
||||||
|
|
||||||
|
```jsonl
|
||||||
|
{"id":"bd-a1b2","title":"Feature A","status":"closed","updated_at":"2025-11-02T10:00:00Z"}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add .beads/beads.jsonl
|
||||||
|
git commit -m "Resolve beads.jsonl merge conflict"
|
||||||
|
bd import # Import to database (will use latest timestamp)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### "fatal: refusing to merge unrelated histories"
|
||||||
|
|
||||||
|
This happens if you created the sync branch independently. Merge with `--allow-unrelated-histories`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git merge beads-metadata --allow-unrelated-histories --no-ff
|
||||||
|
```
|
||||||
|
|
||||||
|
Or use `bd sync --merge` which handles this automatically.
|
||||||
|
|
||||||
|
### "worktree already exists"
|
||||||
|
|
||||||
|
If the worktree is corrupted or in a bad state:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Remove the worktree
|
||||||
|
rm -rf .git/beads-worktrees/beads-metadata
|
||||||
|
|
||||||
|
# Prune stale worktree entries
|
||||||
|
git worktree prune
|
||||||
|
|
||||||
|
# Restart daemon (it will recreate the worktree)
|
||||||
|
bd daemon restart
|
||||||
|
```
|
||||||
|
|
||||||
|
### "branch 'beads-metadata' not found"
|
||||||
|
|
||||||
|
The sync branch doesn't exist yet. The daemon will create it on the first commit. If you want to create it manually:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git checkout -b beads-metadata
|
||||||
|
git checkout main # Switch back
|
||||||
|
```
|
||||||
|
|
||||||
|
Or just let the daemon create it automatically.
|
||||||
|
|
||||||
|
### "Cannot push to protected branch"
|
||||||
|
|
||||||
|
If the sync branch itself is protected:
|
||||||
|
|
||||||
|
1. **Option 1:** Unprotect the sync branch (it's metadata, doesn't need protection)
|
||||||
|
2. **Option 2:** Use `--auto-commit` without `--auto-push`, and push manually when ready
|
||||||
|
3. **Option 3:** Use a different branch name that's not protected
|
||||||
|
|
||||||
|
### Daemon won't start
|
||||||
|
|
||||||
|
Check daemon status and logs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check status
|
||||||
|
bd daemon status
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
tail -f ~/.beads/daemon.log
|
||||||
|
|
||||||
|
# Restart daemon
|
||||||
|
bd daemon restart
|
||||||
|
```
|
||||||
|
|
||||||
|
Common issues:
|
||||||
|
- Port already in use: Another daemon is running
|
||||||
|
- Permission denied: Check `.beads/` directory permissions
|
||||||
|
- Git errors: Ensure git is installed and repository is initialized
|
||||||
|
|
||||||
|
### Changes not syncing between clones
|
||||||
|
|
||||||
|
Ensure all clones are configured the same way:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# On each clone, verify:
|
||||||
|
bd config get sync.branch # Should be the same (e.g., beads-metadata)
|
||||||
|
|
||||||
|
# Pull latest changes
|
||||||
|
bd sync --no-push
|
||||||
|
|
||||||
|
# Check daemon is running
|
||||||
|
bd daemon status
|
||||||
|
```
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
### Do I need to configure anything on GitHub/GitLab?
|
||||||
|
|
||||||
|
No! This is a pure git solution that works on any platform. Just protect your `main` branch as usual.
|
||||||
|
|
||||||
|
### Can I use a different branch name?
|
||||||
|
|
||||||
|
Yes! Use any branch name you want:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bd init --branch my-custom-branch
|
||||||
|
# or
|
||||||
|
bd config set sync.branch my-custom-branch
|
||||||
|
```
|
||||||
|
|
||||||
|
### Can I change the branch name later?
|
||||||
|
|
||||||
|
Yes:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bd config set sync.branch new-branch-name
|
||||||
|
bd daemon restart
|
||||||
|
```
|
||||||
|
|
||||||
|
The old worktree will remain (no harm), and a new worktree will be created for the new branch.
|
||||||
|
|
||||||
|
### What if I want to go back to committing to main?
|
||||||
|
|
||||||
|
Unset the sync branch config:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bd config set sync.branch ""
|
||||||
|
bd daemon restart
|
||||||
|
```
|
||||||
|
|
||||||
|
Beads will go back to committing directly to your current branch.
|
||||||
|
|
||||||
|
### Does this work with multiple collaborators?
|
||||||
|
|
||||||
|
Yes! Each collaborator configures their own sync branch:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# All collaborators use the same branch
|
||||||
|
bd config set sync.branch beads-metadata
|
||||||
|
```
|
||||||
|
|
||||||
|
Everyone's changes sync via the `beads-metadata` branch. Periodically merge to `main` via PR.
|
||||||
|
|
||||||
|
### How often should I merge to main?
|
||||||
|
|
||||||
|
This depends on your workflow:
|
||||||
|
|
||||||
|
- **Daily:** If you want issue history in `main` frequently
|
||||||
|
- **Per sprint:** If you batch metadata updates
|
||||||
|
- **As needed:** Only when you need others to see issue updates
|
||||||
|
|
||||||
|
There's no "right" answer - choose what fits your team.
|
||||||
|
|
||||||
|
### Can I review changes before merging?
|
||||||
|
|
||||||
|
Yes! Use `bd sync --status` to see what's changed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bd sync --status
|
||||||
|
# Shows diff between beads-metadata and main
|
||||||
|
```
|
||||||
|
|
||||||
|
Or create a pull request and review on GitHub/GitLab.
|
||||||
|
|
||||||
|
### What about disk space?
|
||||||
|
|
||||||
|
Worktrees are very lightweight:
|
||||||
|
- Sparse checkout means only `.beads/` is checked out
|
||||||
|
- Typically < 1 MB for the worktree
|
||||||
|
- Shared git history (no duplication)
|
||||||
|
|
||||||
|
### Can I delete the worktree?
|
||||||
|
|
||||||
|
Yes, but the daemon will recreate it. If you want to clean up permanently:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Stop daemon
|
||||||
|
bd daemon stop
|
||||||
|
|
||||||
|
# Remove worktree
|
||||||
|
git worktree remove .git/beads-worktrees/beads-metadata
|
||||||
|
|
||||||
|
# Unset sync branch
|
||||||
|
bd config set sync.branch ""
|
||||||
|
```
|
||||||
|
|
||||||
|
### Does this work with `bd sync`?
|
||||||
|
|
||||||
|
Yes! `bd sync` works normally and includes special commands for the merge workflow:
|
||||||
|
|
||||||
|
- `bd sync --status` - Show diff between branches
|
||||||
|
- `bd sync --merge` - Merge sync branch to main
|
||||||
|
- `bd sync --merge --dry-run` - Preview merge
|
||||||
|
|
||||||
|
### Can AI agents merge automatically?
|
||||||
|
|
||||||
|
Not recommended! Merging to `main` is a deliberate action that should be human-reviewed, especially with protected branches. Agents should create issues and update them; humans should merge to `main`.
|
||||||
|
|
||||||
|
However, if you want fully automated sync:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# WARNING: This bypasses branch protection!
|
||||||
|
bd daemon start --auto-commit --auto-push
|
||||||
|
bd sync --merge # Run periodically (e.g., via cron)
|
||||||
|
```
|
||||||
|
|
||||||
|
### What if I forget to merge for a long time?
|
||||||
|
|
||||||
|
No problem! The sync branch accumulates all changes. When you eventually merge:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bd sync --merge
|
||||||
|
```
|
||||||
|
|
||||||
|
All accumulated changes will be merged at once. Git history will show the full timeline.
|
||||||
|
|
||||||
|
### Can I use this with GitHub Actions or CI/CD?
|
||||||
|
|
||||||
|
Yes! Example GitHub Actions workflow:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: Sync Beads Metadata
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *' # Daily at midnight
|
||||||
|
workflow_dispatch: # Manual trigger
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
sync:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Full history
|
||||||
|
|
||||||
|
- name: Install bd
|
||||||
|
run: |
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
|
||||||
|
|
||||||
|
- name: Pull changes
|
||||||
|
run: |
|
||||||
|
git fetch origin beads-metadata
|
||||||
|
bd sync --no-push
|
||||||
|
|
||||||
|
- name: Merge to main (if changes)
|
||||||
|
run: |
|
||||||
|
if bd sync --status | grep -q 'ahead'; then
|
||||||
|
bd sync --merge
|
||||||
|
git push origin main
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** Make sure the GitHub Action has write permissions to push to `main`.
|
||||||
|
|
||||||
|
## Platform-Specific Notes
|
||||||
|
|
||||||
|
### GitHub
|
||||||
|
|
||||||
|
Protected branch settings:
|
||||||
|
1. Go to Settings → Branches → Add rule
|
||||||
|
2. Branch name pattern: `main`
|
||||||
|
3. Check "Require pull request before merging"
|
||||||
|
4. Save
|
||||||
|
|
||||||
|
Create sync branch PR:
|
||||||
|
```bash
|
||||||
|
git push origin beads-metadata
|
||||||
|
gh pr create --base main --head beads-metadata --title "Update beads metadata"
|
||||||
|
```
|
||||||
|
|
||||||
|
### GitLab
|
||||||
|
|
||||||
|
Protected branch settings:
|
||||||
|
1. Settings → Repository → Protected Branches
|
||||||
|
2. Branch: `main`
|
||||||
|
3. Allowed to merge: Maintainers
|
||||||
|
4. Allowed to push: No one
|
||||||
|
|
||||||
|
Create sync branch MR:
|
||||||
|
```bash
|
||||||
|
git push origin beads-metadata
|
||||||
|
glab mr create --source-branch beads-metadata --target-branch main
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bitbucket
|
||||||
|
|
||||||
|
Protected branch settings:
|
||||||
|
1. Repository settings → Branch permissions
|
||||||
|
2. Branch: `main`
|
||||||
|
3. Check "Prevent direct pushes"
|
||||||
|
|
||||||
|
Create sync branch PR:
|
||||||
|
```bash
|
||||||
|
git push origin beads-metadata
|
||||||
|
# Create PR via Bitbucket web UI
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Topics
|
||||||
|
|
||||||
|
### Multiple Sync Branches
|
||||||
|
|
||||||
|
You can use different sync branches for different purposes:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Development branch
|
||||||
|
bd config set sync.branch beads-dev
|
||||||
|
|
||||||
|
# Production branch
|
||||||
|
bd config set sync.branch beads-prod
|
||||||
|
```
|
||||||
|
|
||||||
|
Switch between them as needed.
|
||||||
|
|
||||||
|
### Syncing with Upstream
|
||||||
|
|
||||||
|
If you're working on a fork:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Add upstream
|
||||||
|
git remote add upstream https://github.com/original/repo.git
|
||||||
|
|
||||||
|
# Fetch upstream changes
|
||||||
|
git fetch upstream
|
||||||
|
|
||||||
|
# Merge upstream beads-metadata to yours
|
||||||
|
git checkout beads-metadata
|
||||||
|
git merge upstream/beads-metadata
|
||||||
|
bd import # Import merged changes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Worktree Location
|
||||||
|
|
||||||
|
By default, worktrees are in `.git/beads-worktrees/`. This is hidden and automatic. If you need a custom location, you'll need to manage worktrees manually (not recommended).
|
||||||
|
|
||||||
|
## Migration Guide
|
||||||
|
|
||||||
|
### From Direct Commits to Sync Branch
|
||||||
|
|
||||||
|
If you have an existing beads setup committing to `main`:
|
||||||
|
|
||||||
|
1. **Set sync branch:**
|
||||||
|
```bash
|
||||||
|
bd config set sync.branch beads-metadata
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Restart daemon:**
|
||||||
|
```bash
|
||||||
|
bd daemon restart
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Verify:**
|
||||||
|
```bash
|
||||||
|
bd config get sync.branch # Should show: beads-metadata
|
||||||
|
```
|
||||||
|
|
||||||
|
Future commits will go to `beads-metadata`. Historical commits on `main` are preserved.
|
||||||
|
|
||||||
|
### From Sync Branch to Direct Commits
|
||||||
|
|
||||||
|
If you want to stop using a sync branch:
|
||||||
|
|
||||||
|
1. **Unset sync branch:**
|
||||||
|
```bash
|
||||||
|
bd config set sync.branch ""
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Restart daemon:**
|
||||||
|
```bash
|
||||||
|
bd daemon restart
|
||||||
|
```
|
||||||
|
|
||||||
|
Future commits will go to your current branch (e.g., `main`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Need help?** Open an issue at https://github.com/steveyegge/beads/issues
|
||||||
281
examples/protected-branch/README.md
Normal file
281
examples/protected-branch/README.md
Normal file
@@ -0,0 +1,281 @@
|
|||||||
|
# Protected Branch Workflow Example
|
||||||
|
|
||||||
|
This example demonstrates how to use beads with protected branches on platforms like GitHub, GitLab, and Bitbucket.
|
||||||
|
|
||||||
|
## Scenario
|
||||||
|
|
||||||
|
You have a repository with:
|
||||||
|
- Protected `main` branch (requires pull requests)
|
||||||
|
- Multiple developers/AI agents working on issues
|
||||||
|
- Desire to track issues in git without bypassing branch protection
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
Use beads' separate sync branch feature to commit issue metadata to a dedicated branch (e.g., `beads-metadata`), then periodically merge via pull request.
|
||||||
|
|
||||||
|
## Quick Demo
|
||||||
|
|
||||||
|
### 1. Setup (One Time)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone this repo or create a new one
|
||||||
|
git init my-project
|
||||||
|
cd my-project
|
||||||
|
|
||||||
|
# Initialize beads with separate sync branch
|
||||||
|
bd init --branch beads-metadata --quiet
|
||||||
|
|
||||||
|
# Verify configuration
|
||||||
|
bd config get sync.branch
|
||||||
|
# Output: beads-metadata
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Create Issues (Agent Workflow)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# AI agent creates issues normally
|
||||||
|
bd create "Implement user authentication" -t feature -p 1
|
||||||
|
bd create "Add login page" -t task -p 1
|
||||||
|
bd create "Write auth tests" -t task -p 2
|
||||||
|
|
||||||
|
# Link tasks to parent feature
|
||||||
|
bd link bd-XXXXX --blocks bd-YYYYY # auth blocks login
|
||||||
|
bd link bd-XXXXX --blocks bd-ZZZZZ # auth blocks tests
|
||||||
|
|
||||||
|
# Start work
|
||||||
|
bd update bd-XXXXX --status in_progress
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** Replace `bd-XXXXX` etc. with actual issue IDs created above.
|
||||||
|
|
||||||
|
### 3. Auto-Sync (Daemon)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start daemon with auto-commit
|
||||||
|
bd daemon start --auto-commit
|
||||||
|
|
||||||
|
# All issue changes are now automatically committed to beads-metadata branch
|
||||||
|
```
|
||||||
|
|
||||||
|
Check what's been committed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# View commits on sync branch
|
||||||
|
git log beads-metadata --oneline | head -5
|
||||||
|
|
||||||
|
# View diff between main and sync branch
|
||||||
|
bd sync --status
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Manual Sync (Without Daemon)
|
||||||
|
|
||||||
|
If you're not using the daemon:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create or update issues
|
||||||
|
bd create "Fix bug in login" -t bug -p 0
|
||||||
|
bd update bd-XXXXX --status closed
|
||||||
|
|
||||||
|
# Manually flush to sync branch
|
||||||
|
bd sync --flush-only
|
||||||
|
|
||||||
|
# Verify commit
|
||||||
|
git log beads-metadata -1
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Merge to Main (Human Review)
|
||||||
|
|
||||||
|
Option 1: Via pull request (recommended):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Push sync branch
|
||||||
|
git push origin beads-metadata
|
||||||
|
|
||||||
|
# Create PR on GitHub
|
||||||
|
gh pr create --base main --head beads-metadata \
|
||||||
|
--title "Update issue metadata" \
|
||||||
|
--body "Automated issue tracker updates from beads"
|
||||||
|
|
||||||
|
# After PR is approved and merged:
|
||||||
|
git checkout main
|
||||||
|
git pull
|
||||||
|
bd import # Import merged changes to database
|
||||||
|
```
|
||||||
|
|
||||||
|
Option 2: Direct merge (if you have push access):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Preview merge
|
||||||
|
bd sync --merge --dry-run
|
||||||
|
|
||||||
|
# Perform merge
|
||||||
|
bd sync --merge
|
||||||
|
|
||||||
|
# This will:
|
||||||
|
# - Merge beads-metadata into main
|
||||||
|
# - Create merge commit
|
||||||
|
# - Push to origin
|
||||||
|
# - Import merged changes
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. Multi-Clone Sync
|
||||||
|
|
||||||
|
If you have multiple clones or agents:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone 1: Create issue
|
||||||
|
bd create "New feature" -t feature -p 1
|
||||||
|
bd sync --flush-only # Commit to beads-metadata
|
||||||
|
git push origin beads-metadata
|
||||||
|
|
||||||
|
# Clone 2: Pull changes
|
||||||
|
git fetch origin beads-metadata
|
||||||
|
bd sync --no-push # Pull from sync branch and import
|
||||||
|
bd list # See the new feature issue
|
||||||
|
```
|
||||||
|
|
||||||
|
## Workflow Summary
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────┐
|
||||||
|
│ Agent creates │
|
||||||
|
│ or updates │
|
||||||
|
│ issues │
|
||||||
|
└────────┬────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────┐
|
||||||
|
│ Daemon (or │
|
||||||
|
│ manual sync) │
|
||||||
|
│ commits to │
|
||||||
|
│ beads-metadata │
|
||||||
|
└────────┬────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────┐
|
||||||
|
│ Periodically │
|
||||||
|
│ merge to main │
|
||||||
|
│ via PR │
|
||||||
|
└────────┬────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────┐
|
||||||
|
│ All clones │
|
||||||
|
│ pull and │
|
||||||
|
│ import │
|
||||||
|
└─────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Directory Structure
|
||||||
|
|
||||||
|
When using separate sync branch, your repo will have:
|
||||||
|
|
||||||
|
```
|
||||||
|
my-project/
|
||||||
|
├── .git/
|
||||||
|
│ ├── beads-worktrees/ # Hidden worktree directory
|
||||||
|
│ │ └── beads-metadata/ # Lightweight checkout of sync branch
|
||||||
|
│ │ └── .beads/
|
||||||
|
│ │ └── beads.jsonl
|
||||||
|
│ └── ...
|
||||||
|
├── .beads/ # Main beads directory (in your workspace)
|
||||||
|
│ ├── beads.db # SQLite database
|
||||||
|
│ ├── beads.jsonl # JSONL export
|
||||||
|
│ └── bd.sock # Daemon socket (if running)
|
||||||
|
├── src/ # Your application code
|
||||||
|
│ └── ...
|
||||||
|
└── README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key points:**
|
||||||
|
- `.git/beads-worktrees/` is hidden from your main workspace
|
||||||
|
- Only `.beads/` is checked out in the worktree (sparse checkout)
|
||||||
|
- Your `src/` code is never affected by beads commits
|
||||||
|
- Minimal disk overhead (~few MB for worktree)
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
### For Humans
|
||||||
|
|
||||||
|
- **Review before merging:** Use `bd sync --status` to see what changed
|
||||||
|
- **Batch merges:** Don't need to merge after every issue - merge when convenient
|
||||||
|
- **PR descriptions:** Link to specific issues in PR body for context
|
||||||
|
|
||||||
|
### For AI Agents
|
||||||
|
|
||||||
|
- **No workflow changes:** Agents use `bd create`, `bd update`, etc. as normal
|
||||||
|
- **Let daemon handle it:** With `--auto-commit`, agents don't think about sync
|
||||||
|
- **Session end:** Run `bd sync` at end of session to ensure everything is committed
|
||||||
|
|
||||||
|
### Troubleshooting
|
||||||
|
|
||||||
|
**"Merge conflicts in beads.jsonl"**
|
||||||
|
|
||||||
|
JSONL is append-only and line-based, so conflicts are rare. If they occur:
|
||||||
|
1. Both versions are usually valid - keep both lines
|
||||||
|
2. If same issue updated differently, keep the line with newer `updated_at`
|
||||||
|
3. After resolving: `bd import` to update database
|
||||||
|
|
||||||
|
**"Worktree doesn't exist"**
|
||||||
|
|
||||||
|
The daemon creates it automatically on first commit. To create manually:
|
||||||
|
```bash
|
||||||
|
bd config get sync.branch # Verify it's set
|
||||||
|
bd daemon restart # Daemon will create worktree
|
||||||
|
```
|
||||||
|
|
||||||
|
**"Changes not syncing"**
|
||||||
|
|
||||||
|
Make sure:
|
||||||
|
- `bd config get sync.branch` returns the same value on all clones
|
||||||
|
- Daemon is running: `bd daemon status`
|
||||||
|
- Both clones have fetched: `git fetch origin beads-metadata`
|
||||||
|
|
||||||
|
## Advanced: GitHub Actions Integration
|
||||||
|
|
||||||
|
Automate the merge process with GitHub Actions:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: Auto-Merge Beads Metadata
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *' # Daily at midnight
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
merge-beads:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Install bd
|
||||||
|
run: curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
|
||||||
|
|
||||||
|
- name: Check for changes
|
||||||
|
id: check
|
||||||
|
run: |
|
||||||
|
git fetch origin beads-metadata
|
||||||
|
if git diff --quiet main origin/beads-metadata -- .beads/; then
|
||||||
|
echo "has_changes=false" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "has_changes=true" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create PR
|
||||||
|
if: steps.check.outputs.has_changes == 'true'
|
||||||
|
run: |
|
||||||
|
gh pr create --base main --head beads-metadata \
|
||||||
|
--title "Update issue metadata" \
|
||||||
|
--body "Automated issue tracker updates from beads" \
|
||||||
|
|| echo "PR already exists"
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
```
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [docs/PROTECTED_BRANCHES.md](../../docs/PROTECTED_BRANCHES.md) - Complete guide
|
||||||
|
- [AGENTS.md](../../AGENTS.md) - Agent integration instructions
|
||||||
|
- [commands/sync.md](../../commands/sync.md) - `bd sync` command reference
|
||||||
Reference in New Issue
Block a user