Skip to content

bd worktree create writes incorrect redirect path (incomplete fix for #1098) #1266

@gulp

Description

@gulp

Summary

bd worktree create generates redirect paths that don't work because the write and read sides use different base directories for relative path resolution.

Root Cause

In cmd/bd/worktree_cmd.go, the code comments say paths should be relative to worktree root:

// Compute relative path from worktree root (not .beads dir) because
// FollowRedirect resolves paths relative to the parent of .beads
worktreeRoot := filepath.Dir(worktreeBeadsDir)
relPath, err := filepath.Rel(worktreeRoot, absMainBeadsDir)

But getRedirectTarget() in the same file resolves from .beads/ directory:

func getRedirectTarget(worktreePath string) string {
    // ...
    if !filepath.IsAbs(target) {
        beadsDir := filepath.Join(worktreePath, ".beads")
        target = filepath.Join(beadsDir, target)  // ← resolves from .beads!
    }
    // ...
}

Steps to Reproduce

cd /home/user/projects/myrepo
bd init
bd worktree create ../myrepo.worktrees/feature-1 --branch feature-1

# Check what bd wrote
cat ../myrepo.worktrees/feature-1/.beads/redirect
# Output: ../../../myrepo/.beads

# Test if it works
cd ../myrepo.worktrees/feature-1
bd list
# Warning: redirect target does not exist or is not a directory: /home/user/myrepo/.beads

Analysis

From /home/user/projects/myrepo.worktrees/feature-1/.beads/:

  • ../../../myrepo/.beads resolves to /home/user/projects/myrepo/.beads

But getRedirectTarget() joins with .beads dir first:

  • filepath.Join(".beads", "../../../myrepo/.beads") → resolves from .beads/
  • Goes only 2 levels up from worktree root → /home/user/myrepo/.beads

Workaround

Manually fix the redirect to be relative to .beads/ directory (add one more ../):

echo "../../../../myrepo/.beads" > .beads/redirect

Or use path relative to worktree root (what the read side actually expects despite the comment):

echo "../../myrepo/.beads" > .beads/redirect

Suggested Fix

Either:

  1. Fix write side to compute path relative to .beads/ directory (matching read side)
  2. Fix read side to resolve from worktree root (matching comment and write side)

Option 1 seems simpler - just remove the filepath.Dir() call:

// relPath, err := filepath.Rel(worktreeRoot, absMainBeadsDir)  // current
relPath, err := filepath.Rel(worktreeBeadsDir, absMainBeadsDir)  // fixed

Environment

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions