- Vendored beads-merge algorithm into internal/merge/ with full MIT license attribution - Created bd merge command as native wrapper (no external binary needed) - Updated bd init to auto-configure git merge driver (both interactive and --quiet) - Removed obsolete test files that were incompatible with vendored version - Added merge to noDbCommands list so it can run standalone - Tested: successful merge and conflict detection work correctly Closes bd-bzfy Thanks to @neongreen for permission to vendor! See: https://github.com/neongreen/mono/issues/240 Original: https://github.com/neongreen/mono/tree/main/beads-merge Amp-Thread-ID: https://ampcode.com/threads/T-f0fe7c4c-13e7-486b-b073-fc64b81eeb4b Co-authored-by: Amp <amp@ampcode.com>
70 lines
2.1 KiB
Go
70 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/spf13/cobra"
|
|
"github.com/steveyegge/beads/internal/merge"
|
|
)
|
|
|
|
var (
|
|
debugMerge bool
|
|
)
|
|
|
|
var mergeCmd = &cobra.Command{
|
|
Use: "merge <output> <base> <left> <right>",
|
|
Short: "3-way merge tool for beads JSONL issue files",
|
|
Long: `bd merge is a 3-way merge tool for beads issue tracker JSONL files.
|
|
|
|
It intelligently merges issues based on identity (id + created_at + created_by),
|
|
applies field-specific merge rules, combines dependencies, and outputs conflict
|
|
markers for unresolvable conflicts.
|
|
|
|
Designed to work as a git merge driver. Configure with:
|
|
|
|
git config merge.beads.driver "bd merge %A %O %L %R"
|
|
git config merge.beads.name "bd JSONL merge driver"
|
|
echo ".beads/beads.jsonl merge=beads" >> .gitattributes
|
|
|
|
Or use 'bd init' which automatically configures the merge driver.
|
|
|
|
Exit codes:
|
|
0 - Merge successful (no conflicts)
|
|
1 - Merge completed with conflicts (conflict markers in output)
|
|
2 - Error (invalid arguments, file not found, etc.)
|
|
|
|
Original tool by @neongreen: https://github.com/neongreen/mono/tree/main/beads-merge
|
|
Vendored into bd with permission.`,
|
|
Args: cobra.ExactArgs(4),
|
|
// PreRun disables PersistentPreRun for this command (no database needed)
|
|
PreRun: func(cmd *cobra.Command, args []string) {},
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
outputPath := args[0]
|
|
basePath := args[1]
|
|
leftPath := args[2]
|
|
rightPath := args[3]
|
|
|
|
err := merge.Merge3Way(outputPath, basePath, leftPath, rightPath, debugMerge)
|
|
if err != nil {
|
|
// Check if error is due to conflicts
|
|
if err.Error() == fmt.Sprintf("merge completed with %d conflicts", 1) ||
|
|
err.Error() == fmt.Sprintf("merge completed with %d conflicts", 2) ||
|
|
err.Error()[:len("merge completed with")] == "merge completed with" {
|
|
// Conflicts present - exit with 1 (standard for merge drivers)
|
|
os.Exit(1)
|
|
}
|
|
// Other errors - exit with 2
|
|
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
|
os.Exit(2)
|
|
}
|
|
// Success - exit with 0
|
|
os.Exit(0)
|
|
},
|
|
}
|
|
|
|
func init() {
|
|
mergeCmd.Flags().BoolVar(&debugMerge, "debug", false, "Enable debug output to stderr")
|
|
rootCmd.AddCommand(mergeCmd)
|
|
}
|