fix: Correct git merge driver placeholders from %L/%R to %A/%B
Git merge drivers only support three placeholders: - %O (ancestor/base) - %A (current version) - %B (other branch's version) The code was incorrectly using %L and %R, which don't exist in git, causing them to be passed through literally and breaking JSONL merges. Changes: - Fixed merge driver config in init.go, merge.go, README.md, docs - Added detection in bd doctor with clear error messages - Added auto-fix in bd doctor --fix - Added proactive warning in bd sync before git pull - Added reactive error detection after merge failures - Updated all tests to use correct placeholders Now users get helpful guidance at every step: 1. bd doctor detects the issue 2. bd doctor --fix auto-corrects it 3. bd sync warns before pulling if misconfigured 4. Error messages suggest bd doctor --fix when merge fails 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -198,9 +198,22 @@ Use --merge to merge the sync branch back to main branch.`,
|
||||
if dryRun {
|
||||
fmt.Println("→ [DRY RUN] Would pull from remote")
|
||||
} else {
|
||||
// Check merge driver configuration before pulling
|
||||
checkMergeDriverConfig()
|
||||
|
||||
fmt.Println("→ Pulling from remote...")
|
||||
if err := gitPull(ctx); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error pulling: %v\n", err)
|
||||
|
||||
// Check if this looks like a merge driver failure
|
||||
errStr := err.Error()
|
||||
if strings.Contains(errStr, "merge driver") ||
|
||||
strings.Contains(errStr, "no such file or directory") ||
|
||||
strings.Contains(errStr, "MERGE DRIVER INVOKED") {
|
||||
fmt.Fprintf(os.Stderr, "\nThis may be caused by an incorrect merge driver configuration.\n")
|
||||
fmt.Fprintf(os.Stderr, "Fix: bd doctor --fix\n\n")
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "Hint: resolve conflicts manually and run 'bd import' then 'bd sync' again\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
@@ -427,6 +440,28 @@ func hasGitRemote(ctx context.Context) bool {
|
||||
|
||||
// gitPull pulls from the current branch's upstream
|
||||
// Returns nil if no remote configured (local-only mode)
|
||||
func checkMergeDriverConfig() {
|
||||
// Get current merge driver configuration
|
||||
cmd := exec.Command("git", "config", "merge.beads.driver")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
// No merge driver configured - this is OK, user may not need it
|
||||
return
|
||||
}
|
||||
|
||||
currentConfig := strings.TrimSpace(string(output))
|
||||
|
||||
// Check if using old incorrect placeholders
|
||||
if strings.Contains(currentConfig, "%L") || strings.Contains(currentConfig, "%R") {
|
||||
fmt.Fprintf(os.Stderr, "\n⚠️ WARNING: Git merge driver is misconfigured!\n")
|
||||
fmt.Fprintf(os.Stderr, " Current: %s\n", currentConfig)
|
||||
fmt.Fprintf(os.Stderr, " Problem: Git only supports %%O (base), %%A (current), %%B (other)\n")
|
||||
fmt.Fprintf(os.Stderr, " Using %%L/%%R will cause merge failures!\n")
|
||||
fmt.Fprintf(os.Stderr, "\n Fix now: bd doctor --fix\n")
|
||||
fmt.Fprintf(os.Stderr, " Or manually: git config merge.beads.driver \"bd merge %%A %%O %%A %%B\"\n\n")
|
||||
}
|
||||
}
|
||||
|
||||
func gitPull(ctx context.Context) error {
|
||||
// Check if any remote exists (bd-biwp: support local-only repos)
|
||||
if !hasGitRemote(ctx) {
|
||||
|
||||
Reference in New Issue
Block a user