feat: add Git worktree compatibility (PR #478)

Adds comprehensive Git worktree support for beads issue tracking:

Core changes:
- New internal/git/gitdir.go package for worktree detection
- GetGitDir() returns proper .git location (main repo, not worktree)
- Updated all hooks to use git.GetGitDir() instead of local helper
- BeadsDir() now prioritizes main repository's .beads directory

Features:
- Hooks auto-install in main repo when run from worktree
- Shared .beads directory across all worktrees
- Config option no-install-hooks to disable auto-install
- New bd worktree subcommand for diagnostics

Documentation:
- New docs/WORKTREES.md with setup instructions
- Updated CHANGELOG.md and AGENT_INSTRUCTIONS.md

Testing:
- Updated tests to use exported git.GetGitDir()
- Added worktree detection tests

Co-authored-by: Claude <noreply@anthropic.com>
Closes: #478
This commit is contained in:
matt wilkie
2025-12-13 10:40:40 -08:00
committed by Steve Yegge
parent de7b511765
commit e01b7412d9
64 changed files with 1895 additions and 3708 deletions

View File

@@ -3,7 +3,6 @@ package fix
import (
"os"
"path/filepath"
"runtime"
"testing"
)
@@ -14,9 +13,6 @@ import (
// - When .beads is a symlink, Permissions() should return nil without changing anything
// - This prevents attempts to chmod symlink targets (which may be read-only like /nix/store)
func TestPermissions_SkipsSymlinkedBeadsDir(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Skipping symlink test on Windows - requires elevated privileges")
}
tmpDir := t.TempDir()
// Create target .beads directory with wrong permissions
@@ -66,9 +62,6 @@ func TestPermissions_SkipsSymlinkedBeadsDir(t *testing.T) {
// TestPermissions_SkipsSymlinkedDatabase verifies that chmod is skipped for
// symlinked database files, but .beads directory permissions are still fixed.
func TestPermissions_SkipsSymlinkedDatabase(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Skipping symlink test on Windows - requires elevated privileges")
}
tmpDir := t.TempDir()
// Create real .beads directory with wrong permissions
@@ -132,9 +125,6 @@ func TestPermissions_SkipsSymlinkedDatabase(t *testing.T) {
// TestPermissions_FixesRegularFiles verifies that permissions ARE fixed for
// regular (non-symlinked) files.
func TestPermissions_FixesRegularFiles(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Skipping permissions test on Windows - Unix-style permissions don't apply")
}
tmpDir := t.TempDir()
// Create .beads directory with wrong permissions