Skip to content

Commit 1c8dd49

Browse files
Steve Yeggeclaude
andcommitted
fix: Auto-repair stale merge driver configs with invalid placeholders
Old bd versions (<0.24.0) installed merge driver with invalid %L/%R placeholders. Git only supports %O (base), %A (current), %B (other). Changes: - mergeDriverInstalled() now detects %L/%R and returns false to trigger repair - bd init automatically fixes stale configs during initialization - bd doctor --fix also repairs stale configs - Added comprehensive test coverage for auto-repair Fixes: bd-3sz0 Epic: bd-tbz3 (all sub-issues now complete) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 49830f7 commit 1c8dd49

2 files changed

Lines changed: 66 additions & 1 deletion

File tree

cmd/bd/init.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ exit 0
752752
return nil
753753
}
754754

755-
// mergeDriverInstalled checks if bd merge driver is configured
755+
// mergeDriverInstalled checks if bd merge driver is configured correctly
756756
func mergeDriverInstalled() bool {
757757
// Check git config for merge driver
758758
cmd := exec.Command("git", "config", "merge.beads.driver")
@@ -761,6 +761,14 @@ func mergeDriverInstalled() bool {
761761
return false
762762
}
763763

764+
// Check if using old invalid placeholders (%L/%R from versions <0.24.0)
765+
// Git only supports %O (base), %A (current), %B (other)
766+
driverConfig := strings.TrimSpace(string(output))
767+
if strings.Contains(driverConfig, "%L") || strings.Contains(driverConfig, "%R") {
768+
// Stale config with invalid placeholders - needs repair
769+
return false
770+
}
771+
764772
// Check if .gitattributes has the merge driver configured
765773
gitattributesPath := ".gitattributes"
766774
content, err := os.ReadFile(gitattributesPath)

cmd/bd/init_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,63 @@ func TestInitMergeDriverAutoConfiguration(t *testing.T) {
791791
t.Errorf("Expected merge.beads.name to contain 'bd', got %q", name)
792792
}
793793
})
794+
795+
t.Run("auto-repair stale merge driver with invalid placeholders", func(t *testing.T) {
796+
// Reset global state
797+
origDBPath := dbPath
798+
defer func() { dbPath = origDBPath }()
799+
dbPath = ""
800+
801+
tmpDir := t.TempDir()
802+
originalWd, err := os.Getwd()
803+
if err != nil {
804+
t.Fatalf("Failed to get working directory: %v", err)
805+
}
806+
defer os.Chdir(originalWd)
807+
808+
if err := os.Chdir(tmpDir); err != nil {
809+
t.Fatalf("Failed to change to temp directory: %v", err)
810+
}
811+
812+
// Initialize git repo
813+
if err := runCommandInDir(tmpDir, "git", "init"); err != nil {
814+
t.Fatalf("Failed to init git: %v", err)
815+
}
816+
817+
// Configure stale merge driver with old invalid placeholders (%L/%R)
818+
// This simulates a user who initialized with bd version <0.24.0
819+
if err := runCommandInDir(tmpDir, "git", "config", "merge.beads.driver", "bd merge %L %R"); err != nil {
820+
t.Fatalf("Failed to set stale git config: %v", err)
821+
}
822+
823+
// Create .gitattributes with merge driver
824+
gitattrsPath := filepath.Join(tmpDir, ".gitattributes")
825+
if err := os.WriteFile(gitattrsPath, []byte(".beads/beads.jsonl merge=beads\n"), 0644); err != nil {
826+
t.Fatalf("Failed to create .gitattributes: %v", err)
827+
}
828+
829+
// Run bd init - should detect stale config and repair it
830+
rootCmd.SetArgs([]string{"init", "--prefix", "test", "--quiet"})
831+
if err := rootCmd.Execute(); err != nil {
832+
t.Fatalf("Init failed: %v", err)
833+
}
834+
835+
// Verify merge driver was updated to correct placeholders
836+
driver, err := runCommandInDirWithOutput(tmpDir, "git", "config", "merge.beads.driver")
837+
if err != nil {
838+
t.Fatalf("Failed to get merge.beads.driver: %v", err)
839+
}
840+
driver = strings.TrimSpace(driver)
841+
expected := "bd merge %A %O %A %B"
842+
if driver != expected {
843+
t.Errorf("Expected merge driver to be repaired to %q, got %q", expected, driver)
844+
}
845+
846+
// Verify it no longer contains invalid placeholders
847+
if strings.Contains(driver, "%L") || strings.Contains(driver, "%R") {
848+
t.Errorf("Merge driver should not contain invalid %%L or %%R placeholders, got %q", driver)
849+
}
850+
})
794851
}
795852

796853
// TestReadFirstIssueFromJSONL_ValidFile verifies reading first issue from valid JSONL

0 commit comments

Comments
 (0)