feat: muse diff <refA> <refB> labels which branch introduced each symbol change (musehub#218)
For the genuine two-ref form, each symbol-level op is now attributed to the branch that introduced it, relative to their merge-base:
M hello.py ├─ added function farewell L4–5 (feature/farewell) └─ function greet (implementation changed) L1–2 (feature/friendlier)
Insert/delete ops are trivially attributable from the diff direction alone (to_ref added it / from_ref had it and lost it) -- no merge-base needed. Replace (modified) ops are genuinely ambiguous without one: the two refs merely differ, and which side actually changed it relative to their common ancestor can't be read off a bare two-way diff. New _compute_symbol_origins finds the merge-base and runs base->from_ref and base->to_ref diffs to determine, per symbol address, whether it changed on from_ref only, to_ref only, or "both" (independently, on both sides -- a genuine three-way divergence worth flagging as such, not attributable to one side).
Additive only, as the ticket itself suggested: new top-level `symbol_origins: {file: {symbol_name: origin}}` JSON key, empty {} for every non-two-ref diff form (HEAD vs working tree, --staged, --shelf, ...) or when no merge-base can be found -- the existing `symbols` key's shape is completely untouched. Text output appends `(branch_name)` after each symbol-level line, only when origins are available.
TDD: wrote 8 new tests in TestSymbolOriginAttribution first -- the ticket's exact repro (added+modified attribution, both text and JSON), the existing `symbols` shape is unchanged (additive-only guard), both sides independently changing the same symbol is labeled "both", and three fall-through guards (HEAD-vs-working-tree, single-ref diff, no merge-base found) all correctly omit origins rather than crashing or guessing. Confirmed genuine RED via muse-dev shelf save/pop isolation -- 7 of 8 failed pre-fix.
Regression: 178 passed across test_cmd_diff.py (full file, 122 tests), test_rename_op.py, test_cmd_merge_dry_run.py, and musehub#219's test_imports_unordered_set_merge.py -- no regressions.
Verified live via muse-dev against a real sandbox repo, reproducing the ticket's exact repro end-to-end -- text and JSON output both match the ticket's own suggested shape precisely.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Semantic Changes
22 symbols
Files Changed
~2
1260 in snapshot
0 comments
muse hub commit comment sha256:72de78de7f68004fd4d89fd1ed31e96734ade136417ac0bc09c151c955540474 --body "your comment"
No comments yet. Be the first to start the discussion.