gabriel / muse public
fix BREAKING merge task/museattributes-permutations #1 / 1
AI Agent gabriel · 160 days ago · Apr 16, 2026 · Diff

fix(merge): honor deletions in ours/theirs strategies; pyproject.toml = manual

- CodePlugin.merge: fix ours/theirs strategies to pop path when the chosen side deleted the file (l is None / r is None). The old 'l or b or ""' pattern fell back to base content, silently resurrecting deleted files. - .museattributes: change pyproject.toml rule from 'ours' to 'manual'. 'ours' silently discards incoming dependency changes from feature branches — a data integrity risk in an agent-first workflow. 'manual' forces human review on any merge that touches pyproject.toml. - tests/test_code_plugin_attributes.py: 101 tests covering all 12 change scenarios × 6 strategies, plus full coverage of every active .museattributes rule. The ours_deleted and theirs_deleted tests were RED before this fix.

sha256:9a4b378124ff81e66ed120cd0fa6620bc5841d7a6dceb678e512fedff492eef8 sha
+109 ~2 symbols
sha256:5daae3bb909a88e0d8abda64d6e48bc612c04314ef65f0c4eb2c5c100e2f092e snapshot
+109
symbols added
~2
symbols modified
0
dead code introduced
Semantic Changes 111 symbols
~ .museattributes .museattributes
~ muse/plugins/code/plugin.py .py 2 symbols modified
~ tests/test_code_plugin_attributes.py .py 109 symbols added
+ PATH variable variable PATH L48–48
+ TestAutoPermutations class class TestAutoPermutations L713–770
+ _m method method _m L716–721
+ test_both_added_different_conflicts method method test_both_added_different_conflicts L752–754
+ test_both_added_same_no_conflict method method test_both_added_same_no_conflict L748–750
+ test_both_deleted_no_conflict method method test_both_deleted_no_conflict L744–746
+ test_convergent method method test_convergent L727–729
+ test_divergent_conflicts method method test_divergent_conflicts L739–742
+ test_only_ours_added method method test_only_ours_ L756–758
+ test_only_theirs_added method method test_only_theirs_ L760–762
+ test_ours_deleted_theirs_modified_conflicts method method test_ours_deleted_theirs_modified_conflicts L764–766
+ test_ours_modified_theirs_deleted_conflicts method method test_ours_modified_theirs_deleted_conflicts L768–770
+ test_ours_only_no_conflict method method test_ours_only_no_conflict L731–733
+ test_theirs_only_no_conflict method method test_theirs_only_no_conflict L735–737
+ test_unchanged method method test_unchanged L723–725
+ TestBasePermutations class class TestBasePermutations L509–569
+ _m method method _m L512–517
+ test_both_added_different_reverts_to_absent method method test_both_added_different_reverts_to_absent L549–554
+ test_both_added_same method method test_both_added_same L545–547
+ test_both_deleted method method test_both_deleted L541–543
+ test_convergent method method test_convergent L523–525
+ test_divergent_deletion_conflict_reverts_to_base method method test_divergent_deletion_conflict_reverts_to_base L564–569
+ test_divergent_reverts_to_base method method test_divergent_reverts_to_base L535–539
+ test_only_ours_added method method test_only_ours_ L556–558
+ test_only_theirs_added method method test_only_theirs_ L560–562
+ test_ours_only method method test_ours_only L527–529
+ test_theirs_only method method test_theirs_only L531–533
+ test_unchanged method method test_unchanged L519–521
+ TestManualPermutations class class TestManualPermutations L635–710
+ _m method method _m L639–644
+ test_both_added_different_forces_conflict method method test_both_added_different_forces_conflict L707–710
+ test_both_added_same_no_conflict method method test_both_added_same_no_conflict L664–668
+ test_both_deleted_no_conflict method method test_both_deleted_no_conflict L658–662
+ test_convergent_no_conflict method method test_convergent_no_conflict L652–656
+ test_divergent_forces_conflict method method test_divergent_forces_conflict L694–697
+ test_only_ours_added_forces_conflict method method test_only_ours_added_forces_conflict L682–686
+ test_only_theirs_added_forces_conflict method method test_only_theirs_added_forces_conflict L688–692
+ test_ours_deleted_theirs_modified_forces_conflict method method test_ours_deleted_theirs_modified_forces_conflict L699–701
+ test_ours_modified_theirs_deleted_forces_conflict method method test_ours_modified_theirs_deleted_forces_conflict L703–705
+ test_ours_only_forces_conflict method method test_ours_only_forces_conflict L670–674
+ test_theirs_only_forces_conflict method method test_theirs_only_forces_conflict L676–680
+ test_unchanged_no_conflict method method test_unchanged_no_conflict L646–650
+ TestMuseAttributesRules class class TestMuseAttributesRules L833–1031
+ _write method method _write L836–837
+ test_commands_divergent_prefers_ours method method test_commands_divergent_prefers_ours L943–951
+ test_core_convergent_no_conflict method method test_core_convergent_no_conflict L871–877
+ test_core_divergent_conflict method method test_core_divergent_conflict L863–869
+ test_core_manual_beats_any_other_rule method method test_core_manual_beats_any_other_rule L1012–1021
+ test_core_rule_beats_lower_priority_wildcard method method test_core_rule_beats_lower_priority_wildcard L879–887
+ test_core_single_branch_change_forces_conflict method method test_core_single_branch_change_forces_conflict L854–861
+ test_core_unchanged_no_false_conflict method method test_core_unchanged_no_false_conflict L843–852
+ test_docs_disjoint_additions_both_kept method method test_docs_disjoint_additions_both_kept L893–901
+ test_docs_divergent_prefers_ours method method test_docs_divergent_prefers_ours L903–912
+ test_nested_md_NOT_matched_by_root_glob method method test_nested_md_NOT_matched_by_root_glob L997–1006
+ test_pyproject_divergent_forces_conflict method method test_pyproject_divergent_forces_conflict L975–981
+ test_pyproject_single_branch_change_forces_conflict method method test_pyproject_single_branch_change_forces_conflict L964–973
+ test_pyproject_unchanged_no_conflict method method test_pyproject_unchanged_no_conflict L958–962
+ test_root_md_union method method test_root_md_union L987–995
+ test_tests_disjoint_files_both_kept method method test_tests_disjoint_files_both_kept L918–926
+ test_tests_same_file_divergent_prefers_ours method method test_tests_same_file_divergent_prefers_ours L928–937
+ test_unmatched_path_gets_auto method method test_unmatched_path_gets_auto L1023–1031
+ TestOursPermutations class class TestOursPermutations L370–437
+ _m method method _m L373–378
+ test_both_added_different_takes_ours method method test_both_added_different_takes_ours L411–415
+ test_both_added_same method method test_both_added_same L407–409
+ test_both_deleted method method test_both_deleted L403–405
+ test_convergent method method test_convergent L384–386
+ test_divergent_takes_ours method method test_divergent_takes_ours L397–401
+ test_only_ours_added method method test_only_ours_ L417–419
+ test_only_theirs_added method method test_only_theirs_ L421–423
+ test_ours_deleted_theirs_modified_ours_wins method method test_ours_deleted_theirs_modified_ours_wins L432–437
+ test_ours_modified_theirs_deleted_takes_ours method method test_ours_modified_theirs_deleted_takes_ours L425–430
+ test_ours_only method method test_ours_only L388–391
+ test_theirs_only method method test_theirs_only L393–395
+ test_unchanged method method test_unchanged L380–382
+ TestTheirsPermutations class class TestTheirsPermutations L440–506
+ _m method method _m L443–448
+ test_both_added_different_takes_theirs method method test_both_added_different_takes_theirs L480–484
+ test_both_added_same method method test_both_added_same L476–478
+ test_both_deleted method method test_both_deleted L472–474
+ test_convergent method method test_convergent L454–456
+ test_divergent_takes_theirs method method test_divergent_takes_theirs L466–470
+ test_only_ours_added method method test_only_ours_ L486–488
+ test_only_theirs_added method method test_only_theirs_ L490–492
+ test_ours_deleted_theirs_modified_takes_theirs method method test_ours_deleted_theirs_modified_takes_theirs L494–499
+ test_ours_modified_theirs_deleted_theirs_wins method method test_ours_modified_theirs_deleted_theirs_wins L501–506
+ test_ours_only method method test_ours_only L458–460
+ test_theirs_only method method test_theirs_only L462–464
+ test_unchanged method method test_unchanged L450–452
+ TestUnionPermutations class class TestUnionPermutations L572–632
+ _m method method _m L575–580
+ test_both_added_different_prefers_ours method method test_both_added_different_prefers_ours L613–617
+ test_both_added_same method method test_both_added_same L609–611
+ test_both_deleted method method test_both_deleted L605–607
+ test_convergent method method test_convergent L586–588
+ test_divergent_prefers_left_for_blobs method method test_divergent_prefers_left_for_blobs L598–603
+ test_only_ours_added method method test_only_ours_ L619–621
+ test_only_theirs_added method method test_only_theirs_ L623–625
+ test_ours_deleted_theirs_modified_keeps_theirs method method test_ours_deleted_theirs_modified_keeps_theirs L627–632
+ test_ours_only method method test_ours_only L590–592
+ test_theirs_only method method test_theirs_only L594–596
+ test_unchanged method method test_unchanged L582–584
+ _ALT variable variable _ALT L46–46
+ _MUSE_ATTRS variable variable _MUSE_ATTRS L785–830
+ _NEW variable variable _NEW L45–45
+ _OLD variable variable _OLD L44–44
+ _files function function _files L72–73
+ _merge function function _merge L63–69
+ _rule function function _rule L51–52
← Older Oldest on task/museattributes-permutations
All commits
Newer → Latest on task/museattributes-permutations

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:9a4b378124ff81e66ed120cd0fa6620bc5841d7a6dceb678e512fedff492eef8 --body "your comment"