Back to Beads

Git Integration Guide

docs/GIT_INTEGRATION.md

1.0.310.9 KB
Original Source

Git Integration Guide

For: AI agents and developers managing bd git workflows

Overview

bd integrates with git for worktree support and protected branch workflows. The Dolt backend handles all data storage and versioning natively.

Git Worktrees

Beads has comprehensive Git worktree compatibility with shared database architecture.

How It Works

Git worktrees share the same .git directory and .beads database:

  • All worktrees use the same .beads/dolt/ database in the main repository
  • Database discovery prioritizes main repository location
  • Worktree-aware git operations prevent conflicts

Worktree-Aware Features

Database Discovery:

  • Resolves the active workspace using BEADS_DIR, worktree fallback, and shared main-repo .beads
  • Falls back to worktree-local search if needed
  • Prevents database duplication across worktrees
  • Use bd where as the authoritative check; local ./.beads may be absent in pure worktree or redirected setups

Git Operations:

  • Worktree-aware repository root detection
  • Proper handling of git directory vs git common directory
  • Safe concurrent access to shared database (use server mode for multi-writer)

Protected Branch Workflows

Note: Beads data is stored in Dolt under refs/dolt/data, separate from standard Git refs. This means beads does not commit to any Git branch, so protected branch workflows are not affected.

Sync with remotes using Dolt's native push/pull:

bash
bd dolt push    # Push changes to Dolt remote
bd dolt pull    # Pull changes from Dolt remote

Daily Workflow (Unchanged for Agents)

bash
# Agents work normally - no changes needed!
bd create "Fix authentication" -t bug -p 1
bd update bd-a1b2 --claim
bd close bd-a1b2 "Fixed"

Merging to Main (Humans)

bash
# Check what's changed
bd dolt show

# Option 1: Create pull request
git push origin beads-sync
# Then create PR on GitHub/GitLab

# Option 2: Direct merge (if allowed)
git merge beads-sync

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 PROTECTED_BRANCHES.md for complete setup guide, troubleshooting, and examples.

Branchless Workflows (Jujutsu / jj)

Beads works with branchless VCS tools like Jujutsu (jj). Since beads data is stored in Dolt (not git branches), there is no dependency on the "current branch" concept.

What Works Without Hooks

All core beads functionality works without git hooks:

FeatureHooks Required?Notes
bd create, bd update, bd closeNoCore CRUD uses Dolt directly
bd ready, bd list, bd showNoRead-only queries
bd dolt push / bd dolt pullNoDolt-native sync, independent of git
bd onboard, bd doctorNoDiagnostics and onboarding
Agent identity trailersYesprepare-commit-msg hook adds Executed-By: to commits
Hook chainingYesPreserves existing pre-commit, post-merge hooks

To skip hooks entirely during init:

bash
bd init --skip-hooks

What Works Without AGENTS.md

The AGENTS.md file generated by bd init provides AI agent instructions (including "Landing the Plane" push/pull workflow). If you manage your own agent instructions or don't want beads to modify tracked files:

bash
bd init --skip-agents    # Skip AGENTS.md and Claude settings generation
bd init --stealth        # Full invisible mode (also skips hooks + agents)

Jujutsu Setup

Colocated repos (jj git init --colocate): Git hooks work normally. Beads installs simplified hooks (no staging logic).

Pure jj repos (no git): Since jj doesn't have native hooks yet, set up push aliases:

toml
# ~/.config/jj/config.toml
[aliases]
push = ["util", "exec", "--", "sh", "-c", "bd dolt commit && bd dolt push && jj git push \"$@\"", ""]

Merge Conflicts

Configure jj to use beads' merge driver for .beads/issues.jsonl:

toml
# ~/.config/jj/config.toml
[merge-tools.beads-merge]
program = "bd"
merge-args = ["merge", "$output", "$base", "$left", "$right"]
merge-conflict-exit-codes = [1]

Then resolve with: jj resolve --tool=beads-merge .beads/issues.jsonl

Git Hooks

External Hook Manager Support

bd detects and integrates with these external git hook managers:

  • lefthook — YAML/TOML/JSON config
  • husky.husky/ directory scripts
  • pre-commit.pre-commit-config.yaml
  • prek — Rust-based pre-commit alternative (same config)
  • hk — Fast hook manager using Pkl config
  • overcommit — Ruby-based (detection only)
  • simple-git-hooks — Lightweight JS (detection only)

When an external hook manager is detected, bd hooks install uses --chain to preserve existing hooks.

hk Integration Example

Add bd hooks to your hk.pkl:

pkl
hooks {
    ["pre-commit"] {
        steps {
            ["bd-pre-commit"] {
                check = "bd hooks run pre-commit"
            }
        }
    }
    ["post-merge"] {
        steps {
            ["bd-post-merge"] {
                check = "bd hooks run post-merge"
            }
        }
    }
    ["pre-push"] {
        steps {
            ["bd-pre-push"] {
                check = "bd hooks run pre-push \"$@\""
            }
        }
    }
}

Installation

bash
# Install hooks
bd hooks install --beads

What Gets Installed

pre-commit hook:

  • Runs pre-commit checks for beads data consistency

post-merge hook:

  • Ensures Dolt database is current after pull/merge operations

Hook Timeout

The beads hook shim wraps bd hooks run with an OS-level timeout to prevent hooks from hanging git operations indefinitely. The default timeout is 300 seconds (5 minutes), which accommodates repos with chained pre-commit pipelines (e.g., eslint, prettier, TypeScript compilation).

If your chained hooks need more time, override the timeout with the BEADS_HOOK_TIMEOUT environment variable:

bash
# Set a longer timeout (in seconds)
export BEADS_HOOK_TIMEOUT=600  # 10 minutes

# Or set it per-invocation
BEADS_HOOK_TIMEOUT=600 git commit -m "..."

When the timeout is reached, beads prints a warning and allows the git operation to proceed (the commit/push is not blocked).

Hook Implementation Details

Hook Installation (cmd/bd/hooks.go)

The installHooks() function:

  • Writes embedded hook scripts to the .git/hooks/ directory
  • Creates the hooks directory with os.MkdirAll() if needed
  • Backs up existing hooks with .backup extension (unless --force flag used)
  • Sets execute permissions (0755) on installed hooks
  • Supports shared mode via --shared flag (installs to .beads-hooks/ instead)

Git Directory Resolution

Critical for worktree support: The getGitDir() helper uses git rev-parse --git-dir to resolve the actual git directory:

go
// Returns ".git" in normal repos
// Returns "/path/to/shared/.git" in git worktrees
gitDir, err := getGitDir()

In normal repositories, .git is a directory containing the git internals. In git worktrees, .git is a file containing gitdir: /path/to/actual/git/dir.

Hook Detection (cmd/bd/init.go)

The detectExistingHooks() function scans for existing hooks and classifies them:

  • bd hooks: Identified by "bd (beads) pre-commit hook" comment in content
  • pre-commit framework hooks: Detected by "pre-commit framework" or "pre-commit.com" in content
  • Custom hooks: Any other existing hook

Multi-Workspace Sync

Fork-Based Pattern

┌──────────────┐      ┌─────────────────┐
│  OSS Contrib │─────▶│ Planning Repo   │
│  (Fork)      │      │ (.beads/dolt/)  │
└──────────────┘      └─────────────────┘
       │
       │ PR
       ▼
┌─────────────────┐
│ Upstream Repo   │
│ (no .beads/)    │
└─────────────────┘

Best for:

  • Open source contributors
  • Solo developers
  • Private task tracking on public repos

Setup:

bash
bd init --contributor  # Interactive wizard

Team Branch Pattern

┌──────────────┐
│  Team Member │────┐
│  (main)      │    │
└──────────────┘    │
                    ▼
┌──────────────┐  ┌─────────────────┐
│  Team Member │─▶│ Shared Repo     │
│  (main)      │  │ (beads-sync)    │
└──────────────┘  └─────────────────┘

Best for:

  • Teams on protected branches
  • Managed git workflows
  • Review-before-merge policies

Setup:

bash
bd init --team  # Interactive wizard

See MULTI_REPO_MIGRATION.md for complete guide.

Git Configuration Best Practices

# Dolt database (not tracked in git)
.beads/dolt/

Git LFS Considerations

The Dolt database directory (.beads/dolt/) should be gitignored, not tracked via LFS or regular git.

Custom Merge Driver

bd includes a built-in merge driver for resolving conflicts in .beads/issues.jsonl files. This replaces the standalone beads-merge binary that was previously maintained in a separate repository.

Alternative: Standalone beads-merge Binary (Deprecated)

⚠️ Deprecated: The standalone beads-merge binary (previously hosted at github.com/neongreen/mono) is no longer maintained and may be incompatible with current versions of bd. Use bd merge instead.

The built-in bd merge command provides the same functionality:

bash
bd merge <output> <base> <left> <right>

Jujutsu Integration

See also: Branchless Workflows for a complete guide.

For Jujutsu users, add to ~/.config/jj/config.toml:

toml
[merge-tools.beads-merge]
program = "bd"
merge-args = ["merge", "$output", "$base", "$left", "$right"]
merge-conflict-exit-codes = [1]

Then resolve conflicts with:

bash
jj resolve --tool=beads-merge .beads/issues.jsonl

This configures Jujutsu to invoke bd merge as its merge tool, restricted to .beads/issues.jsonl (since it only handles beads data conflicts, not general file conflicts).

See Also