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:
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/steveyegge/beads/internal/git"
|
||||
"github.com/steveyegge/beads/internal/storage/sqlite"
|
||||
)
|
||||
|
||||
@@ -37,34 +38,37 @@ func failIfProductionDatabase(t *testing.T, dbPath string) {
|
||||
return
|
||||
}
|
||||
|
||||
// Check if database is in a directory that contains .git
|
||||
dir := filepath.Dir(absPath)
|
||||
for {
|
||||
gitPath := filepath.Join(dir, ".git")
|
||||
if _, err := os.Stat(gitPath); err == nil {
|
||||
// Found .git directory - check if this is a test or production database
|
||||
beadsPath := filepath.Join(dir, ".beads")
|
||||
if strings.HasPrefix(absPath, beadsPath) {
|
||||
// Database is in .beads/ directory of a git repository
|
||||
// This is ONLY allowed if we're in a temp directory
|
||||
if !strings.Contains(absPath, os.TempDir()) {
|
||||
t.Fatalf("PRODUCTION DATABASE POLLUTION DETECTED (bd-2c5a):\n"+
|
||||
" Database: %s\n"+
|
||||
" Git repo: %s\n"+
|
||||
" Tests MUST use t.TempDir() or tempfile to create isolated databases.\n"+
|
||||
" This prevents test issues from polluting the production database.",
|
||||
absPath, dir)
|
||||
}
|
||||
}
|
||||
break
|
||||
// Use worktree-aware git directory detection
|
||||
gitDir, err := git.GetGitDir()
|
||||
if err != nil {
|
||||
// Not a git repository, no pollution risk
|
||||
return
|
||||
}
|
||||
|
||||
// Check if database is in .beads/ directory of this git repository
|
||||
beadsPath := ""
|
||||
gitDirAbs, err := filepath.Abs(gitDir)
|
||||
if err != nil {
|
||||
t.Logf("Warning: Could not get absolute path for git dir %s: %v", gitDir, err)
|
||||
return
|
||||
}
|
||||
|
||||
// The .beads directory should be at the root of the git repository
|
||||
// For worktrees, gitDir points to the main repo's .git directory
|
||||
repoRoot := filepath.Dir(gitDirAbs)
|
||||
beadsPath = filepath.Join(repoRoot, ".beads")
|
||||
|
||||
if strings.HasPrefix(absPath, beadsPath) {
|
||||
// Database is in .beads/ directory of a git repository
|
||||
// This is ONLY allowed if we're in a temp directory
|
||||
if !strings.Contains(absPath, os.TempDir()) {
|
||||
t.Fatalf("PRODUCTION DATABASE POLLUTION DETECTED (bd-2c5a):\n"+
|
||||
" Database: %s\n"+
|
||||
" Git repo: %s\n"+
|
||||
" Tests MUST use t.TempDir() or tempfile to create isolated databases.\n"+
|
||||
" This prevents test issues from polluting the production database.",
|
||||
absPath, repoRoot)
|
||||
}
|
||||
|
||||
parent := filepath.Dir(dir)
|
||||
if parent == dir {
|
||||
// Reached filesystem root
|
||||
break
|
||||
}
|
||||
dir = parent
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user