gabriel / muse public
feat patch task/bridge-phase3 #1 / 1
AI Agent gabriel · 145 days ago · Apr 27, 2026 · Diff

feat: implement muse bridge git-export Phase 3

GitExporter class: resolve_muse_ref, read_snapshot, sync_to_git, fix_file_modes, git_commit, git_push. _ensure_git_branch helper creates/checks-out target branch. _watch_loop for --watch polling mode (NDJSON events). run_git_export: full implementation replacing Phase 2 stub. Glob/fnmatch support in sync_to_git for --exclude patterns. Branch name safety validation (_BRANCH_SAFE_RE). 8-tier tests in tests/test_bridge_git_export.py (37 tests, all passing).

sha256:de3a6b1c163ebd89937bb0823f4d47807c7ccb774cb1b697107358c2e1037469 sha
+75 ~1 symbols
sha256:e8d98bc5f7adc0d8ff7db8a36377d096c187069fff1b5f46cd042348df436d72 snapshot
+75
symbols added
~1
symbol modified
0
dead code introduced
Semantic Changes 76 symbols
~ tests/test_bridge_git_export.py .py 63 symbols added
+ TestDataIntegrity class class TestDataIntegrity L614–717
+ test_bridge_state_git_sha_matches_git_log method method test_bridge_state_git_sha_matches_git_log L671–692
+ test_exported_file_sha256_matches_muse_object_store method method test_exported_file_sha256_matches_muse_object_store L617–645
+ test_git_commit_message_contains_muse_commit_id method method test_git_commit_message_contains_muse_commit_id L647–669
+ test_muse_commit_id_in_json_output_matches_bridge_state method method test_muse_commit_id_in_json_output_matches_bridge_state L694–717
+ TestDocstrings class class TestDocstrings L872–891
+ test_git_exporter_has_class_docstring class method test_git_exporter_has_class_docstring L875–878
+ test_run_git_export_has_docstring_mentioning_ci method method test_run_git_export_has_docstring_mentioning_ci L885–891
+ test_sync_to_git_has_docstring method method test_sync_to_git_has_docstring L880–883
+ TestEdgeCases class class TestEdgeCases L427–568
+ test_allow_empty_creates_commit_with_no_changes method method test_allow_empty_creates_commit_with_no_changes L491–524
+ test_git_branch_not_yet_in_git_is_created method method test_git_branch_not_yet_in_git_is_created L447–471
+ test_git_dir_not_git_repo_exits_user_error method method test_git_dir_not_git_repo_exits_user_error L430–445
+ test_git_dir_with_dirty_working_tree_proceeds method method test_git_dir_with_dirty_working_tree_proceeds L549–568
+ test_muse_ref_nonexistent_branch_exits_user_error method method test_muse_ref_nonexistent_branch_exits_user_error L473–489
+ test_spaces_in_file_path_exported_correctly method method test_spaces_in_file_path_exported_correctly L526–547
+ TestPerformance class class TestPerformance L725–781
+ test_delete_replace_200_files_under_5s method method test_delete_replace_200_files_under_5s L729–758
+ test_full_export_cycle_200_files_under_10s method method test_full_export_cycle_200_files_under_10s L761–781
+ TestRoundTrip class class TestRoundTrip L226–419
+ test_bridge_state_last_export_written method method test_bridge_state_last_export_written L344–363
+ test_exclude_pattern_omits_files method method test_exclude_pattern_omits_files L321–342
+ test_export_creates_git_commit method method test_export_creates_git_commit L229–244
+ test_export_produces_mirror_commit_message method method test_export_produces_mirror_commit_message L246–264
+ test_export_twice_no_new_muse_commit_no_new_git_commit method method test_export_twice_no_new_muse_commit_no_new_git_commit L266–296
+ test_fix_modes_sets_644_on_files method method test_fix_modes_sets_644_on_files L298–319
+ test_git_bridge_toml_absent_from_git_tree method method test_git_bridge_toml_absent_from_git_tree L405–419
+ test_muse_dir_absent_from_git_tree method method test_muse_dir_absent_from_git_tree L383–403
+ test_no_push_does_not_push method method test_no_push_does_not_push L365–381
+ TestSchemaFlags class class TestSchemaFlags L150–218
+ test_default_commit_message_contains_commit_id_placeholder method method test_default_commit_message_contains_commit_id_placeholder L195–197
+ test_dry_run_emits_json_with_dry_run_true method method test_dry_run_emits_json_with_dry_run_true L177–193
+ test_help_has_fix_modes method method test_help_has_fix_modes L169–171
+ test_help_has_git_branch method method test_help_has_git_branch L161–163
+ test_help_has_git_dir method method test_help_has_git_dir L157–159
+ test_help_has_muse_ref method method test_help_has_muse_ref L153–155
+ test_help_has_no_push method method test_help_has_no_push L165–167
+ test_help_has_watch method method test_help_has_watch L173–175
+ test_strip_muse_metadata_default_true method method test_strip_muse_metadata_default_true L199–218
+ TestSecurity class class TestSecurity L789–864
+ test_fix_modes_does_not_chmod_git_directory method method test_fix_modes_does_not_chmod_git_directory L838–864
+ test_git_branch_with_semicolon_is_rejected method method test_git_branch_with_semicolon_is_rejected L819–836
+ test_shell_injection_in_commit_message_is_safe method method test_shell_injection_in_commit_message_is_safe L792–817
+ TestStress class class TestStress L576–606
+ test_export_500_files_completes_under_15s method method test_export_500_files_completes_under_15s L580–606
+ _git_file_content function function _git_file_content L140–142
+ _git_file_list function function _git_file_list L129–137
+ _git_latest_message function function _git_latest_message L120–126
+ _git_latest_sha function function _git_latest_sha L111–117
+ _git_log_count function function _git_log_count L100–108
+ _invoke function function _invoke L40–42
+ _make_git_repo function function _make_git_repo L45–65
+ _make_muse_repo function function _make_muse_repo L68–97
+ CliRunner import import CliRunner L30–30
+ annotations import import annotations L19–19
+ hashlib import import hashlib L21–21
+ json import import json L22–22
+ os import import os L23–23
+ pathlib import import pathlib L24–24
+ pytest import import pytest L28–28
+ subprocess import import subprocess L25–25
+ time import import time L26–26
+ runner variable variable runner L32–32
~ muse/cli/commands/bridge.py .py 12 symbols added, 1 symbol modified
+ GitExporter class class GitExporter L1321–1655
+ __init__ method method __init__ L1353–1377
+ _user_error method method _user_error L1383–1386
+ fix_file_modes method method fix_file_modes L1563–1584
+ git_commit method method git_commit L1590–1642
+ git_push method method git_push L1644–1655
+ read_snapshot method method read_snapshot L1458–1478
+ resolve_muse_ref method method resolve_muse_ref L1392–1452
+ sync_to_git method method sync_to_git L1484–1561
+ _BRANCH_SAFE_RE variable variable _BRANCH_SAFE_RE L1318–1318
+ _ensure_git_branch function function _ensure_git_branch L1658–1684
+ _watch_loop function function _watch_loop L1687–1769
← Older Oldest on task/bridge-phase3
All commits
Newer → Latest on task/bridge-phase3

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:de3a6b1c163ebd89937bb0823f4d47807c7ccb774cb1b697107358c2e1037469 --body "your comment"