fix(duplicates): prefer issues with children/deps when choosing merge target (GH#1022)

The duplicate merge target selection now considers structural relationships:
1. Dependent count (children, blocked-by) - highest priority
2. Text reference count - secondary
3. Lexicographically smallest ID - tiebreaker

This fixes the bug where `bd duplicates --auto-merge` would suggest closing
an epic with 17 children instead of the empty shell duplicate.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
emma
2026-01-12 00:45:25 -08:00
committed by Steve Yegge
parent 8395105493
commit 1c1dabcfdd
3 changed files with 153 additions and 25 deletions

View File

@@ -466,21 +466,26 @@ NOTE: Import requires direct database access and does not work with daemon mode.
}
refCounts := countReferences(allIssues)
structuralScores := countStructuralRelationships(duplicateGroups)
fmt.Fprintf(os.Stderr, "Found %d duplicate group(s)\n\n", len(duplicateGroups))
for i, group := range duplicateGroups {
target := chooseMergeTarget(group, refCounts)
target := chooseMergeTarget(group, refCounts, structuralScores)
fmt.Fprintf(os.Stderr, "Group %d: %s\n", i+1, group[0].Title)
for _, issue := range group {
refs := refCounts[issue.ID]
depCount := 0
if score, ok := structuralScores[issue.ID]; ok {
depCount = score.dependentCount
}
marker := " "
if issue.ID == target.ID {
marker = "→ "
}
fmt.Fprintf(os.Stderr, " %s%s (%s, P%d, %d refs)\n",
marker, issue.ID, issue.Status, issue.Priority, refs)
fmt.Fprintf(os.Stderr, " %s%s (%s, P%d, %d dependents, %d refs)\n",
marker, issue.ID, issue.Status, issue.Priority, depCount, refs)
}
sources := make([]string, 0, len(group)-1)