fix: bd sync fails with exit 128 in bare repo worktrees (GH#827)
Two fixes for bare repo worktree setups: 1. fork_protection.go: Use git.GetGitDir() instead of hardcoding .git In worktrees, .git is a file containing gitdir path, not a directory. Using GetGitDir() handles this correctly. 2. sync_git.go: Simplify gitHasBeadsChanges to use absolute paths The previous code used git -C main-repo-root status, but in bare repo worktrees GetMainRepoRoot() returns the parent of the bare repo which is not a valid working tree. Using absolute paths without -C lets git find the repo from cwd, which always works. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Steve Yegge
parent
95f14fa827
commit
363c5a3819
@@ -43,8 +43,15 @@ func ensureForkProtection() {
|
||||
return // Not a fork of beads, user's own project
|
||||
}
|
||||
|
||||
// Get actual git directory (handles worktrees where .git is a file) (GH#827)
|
||||
gitDir, err := git.GetGitDir()
|
||||
if err != nil {
|
||||
debug.Printf("fork protection: failed to get git dir: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if already excluded
|
||||
excludePath := filepath.Join(gitRoot, ".git", "info", "exclude")
|
||||
excludePath := filepath.Join(gitDir, "info", "exclude")
|
||||
if isAlreadyExcluded(excludePath) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ func getRepoRootForWorktree(_ context.Context) string {
|
||||
}
|
||||
|
||||
// gitHasBeadsChanges checks if any tracked files in .beads/ have uncommitted changes
|
||||
// This function is worktree-aware and handles bare repo worktree setups (GH#827).
|
||||
func gitHasBeadsChanges(ctx context.Context) (bool, error) {
|
||||
// Get the absolute path to .beads directory
|
||||
beadsDir := beads.FindBeadsDir()
|
||||
@@ -96,26 +97,12 @@ func gitHasBeadsChanges(ctx context.Context) (bool, error) {
|
||||
return false, fmt.Errorf("no .beads directory found")
|
||||
}
|
||||
|
||||
// Get the repository root (handles worktrees properly)
|
||||
repoRoot := getRepoRootForWorktree(ctx)
|
||||
if repoRoot == "" {
|
||||
return false, fmt.Errorf("cannot determine repository root")
|
||||
}
|
||||
|
||||
// Compute relative path from repo root to .beads
|
||||
relPath, err := filepath.Rel(repoRoot, beadsDir)
|
||||
if err != nil {
|
||||
// Fall back to absolute path if relative path fails
|
||||
statusCmd := exec.CommandContext(ctx, "git", "status", "--porcelain", beadsDir) //nolint:gosec // G204: beadsDir from beads.FindBeadsDir()
|
||||
statusOutput, err := statusCmd.Output()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("git status failed: %w", err)
|
||||
}
|
||||
return len(strings.TrimSpace(string(statusOutput))) > 0, nil
|
||||
}
|
||||
|
||||
// Run git status with relative path from repo root
|
||||
statusCmd := exec.CommandContext(ctx, "git", "-C", repoRoot, "status", "--porcelain", relPath) //nolint:gosec // G204: paths from internal git helpers
|
||||
// Run git status with absolute path from current directory.
|
||||
// This is more robust than using -C with a repo root, because:
|
||||
// 1. In bare repo worktree setups, GetMainRepoRoot() returns the parent
|
||||
// of the bare repo, which isn't a valid working tree (GH#827)
|
||||
// 2. Git will find the repository from cwd, which is always valid
|
||||
statusCmd := exec.CommandContext(ctx, "git", "status", "--porcelain", beadsDir) //nolint:gosec // G204: beadsDir from beads.FindBeadsDir()
|
||||
statusOutput, err := statusCmd.Output()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("git status failed: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user