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

feat: implement muse bridge git-import Phase 2

Full git-to-Muse import engine replacing the Phase 1 stub.

New symbols in bridge.py: - _DEFAULT_EXCLUDE_PREFIXES / _DEFAULT_EXCLUDE_SUFFIXES — default path filters - _should_exclude() — path exclusion predicate - AttributionMapper — email-to-handle mapping with synthetic fallback - _CatFile — long-running git cat-file --batch process manager - _git() — thin subprocess wrapper - _batch_commit_log() — oldest-first commit list with NUL-delimited format - _batch_diff_tree() — per-commit file diff → {path: blob_sha|None} - _is_lfs_pointer() — LFS pointer detection - _parse_sem_ver_bump() — conventional commit → semver bump level - _replay_commit() — single commit replay into Muse object store - _replay_branch() — full branch replay orchestrator with reflog - _list_git_branches() / _list_git_tags() — git metadata helpers - _import_tags() — git tag → Muse TagRecord import - run_git_import() — full CLI entry point (replaces stub)

New test file: tests/test_bridge_git_import.py (41 tests, 8 tiers). All 41 tests pass in ~12s.

sha256:0e4a3658a1cd02c58d1ad373dded35e9d22618c514a51b37a09c14e04d093fbe sha
+93 ~2 symbols
sha256:c1f6d2f80d3e22a3a26034ade0c6dd579f0ee837d83b5ad91df93e45d2fb6c69 snapshot
+93
symbols added
~2
symbols modified
0
dead code introduced
Semantic Changes 95 symbols
~ tests/test_bridge_git_import.py .py 63 symbols added
+ TestDataIntegrity class class TestDataIntegrity L697–780
+ test_no_duplicate_objects_on_reimport method method test_no_duplicate_objects_on_reimport L734–758
+ test_reflog_appended method method test_reflog_appended L760–780
+ test_sha256_of_blob_matches_object_store method method test_sha256_of_blob_matches_object_store L700–732
+ TestDocstrings class class TestDocstrings L899–920
+ test_attribution_mapper_has_docstring method method test_attribution_mapper_has_docstring L910–912
+ test_batch_commit_log_has_docstring method method test_batch_commit_log_has_docstring L918–920
+ test_cat_file_has_docstring method method test_cat_file_has_docstring L906–908
+ test_replay_branch_has_docstring method method test_replay_branch_has_docstring L914–916
+ test_replay_commit_has_docstring method method test_replay_commit_has_docstring L902–904
+ TestEdgeCases class class TestEdgeCases L432–636
+ test_conventional_commit_breaking_becomes_major_bump method method test_conventional_commit_breaking_becomes_major_bump L617–636
+ test_conventional_commit_feat_becomes_minor_bump method method test_conventional_commit_feat_becomes_minor_bump L573–594
+ test_conventional_commit_fix_becomes_patch_bump method method test_conventional_commit_fix_becomes_patch_bump L596–615
+ test_empty_git_repo_exits_zero method method test_empty_git_repo_exits_zero L435–466
+ test_excluded_file_not_in_manifest method method test_excluded_file_not_in_manifest L541–571
+ test_from_ref_nonexistent_exits_user_error method method test_from_ref_nonexistent_exits_user_error L468–486
+ test_incremental_no_bridge_state_does_full_import method method test_incremental_no_bridge_state_does_full_import L488–506
+ test_lfs_pointer_skipped_with_lfs_skip method method test_lfs_pointer_skipped_with_lfs_skip L508–539
+ TestPerformance class class TestPerformance L787–840
+ test_100_commit_import_under_5_seconds method method test_100_commit_import_under_5_seconds L791–809
+ test_incremental_1_commit_under_500ms method method test_incremental_1_commit_under_500ms L812–840
+ TestRoundTrip class class TestRoundTrip L199–425
+ test_attribution_map_applies method method test_attribution_map_applies L309–338
+ test_bridge_state_written_after_import method method test_bridge_state_written_after_import L365–381
+ test_file_content_preserved method method test_file_content_preserved L383–425
+ test_import_2_branches method method test_import_2_branches L238–263
+ test_import_3_commits_creates_3_muse_commits method method test_import_3_commits_creates_3_muse_commits L202–220
+ test_import_creates_expected_branch method method test_import_creates_expected_branch L222–236
+ test_incremental_import_only_imports_new method method test_incremental_import_only_imports_new L265–307
+ test_unmapped_email_gets_synthetic_handle method method test_unmapped_email_gets_synthetic_handle L340–363
+ TestSchemaFlags class class TestSchemaFlags L121–192
+ test_default_excludes_cover_git_dir method method test_default_excludes_cover_git_dir L172–175
+ test_default_excludes_cover_node_modules method method test_default_excludes_cover_node_modules L177–179
+ test_default_excludes_cover_pyc method method test_default_excludes_cover_pyc L181–183
+ test_default_excludes_cover_venv method method test_default_excludes_cover_venv L185–187
+ test_dry_run_writes_nothing method method test_dry_run_writes_nothing L136–153
+ test_help_contains_attribution_map method method test_help_contains_attribution_map L128–130
+ test_help_contains_import_tags method method test_help_contains_import_tags L132–134
+ test_help_contains_incremental_flag method method test_help_contains_incremental_flag L124–126
+ test_json_output_valid_ndjson method method test_json_output_valid_ndjson L155–170
+ test_non_excluded_path method method test_non_excluded_path L189–192
+ TestSecurity class class TestSecurity L847–892
+ test_attribution_map_control_chars_rejected method method test_attribution_map_control_chars_rejected L871–880
+ test_git_commit_message_ansi_stripped method method test_git_commit_message_ansi_stripped L850–869
+ test_source_path_traversal_rejected method method test_source_path_traversal_rejected L882–892
+ TestStress class class TestStress L643–690
+ test_cat_file_stays_alive method method test_cat_file_stays_alive L672–690
+ test_import_100_commits method method test_import_100_commits L646–670
+ _get_muse_branches function function _get_muse_branches L103–114
+ _get_muse_log function function _get_muse_log L91–100
+ _invoke function function _invoke L38–40
+ _make_git_repo function function _make_git_repo L43–80
+ _make_muse_repo function function _make_muse_repo L83–88
+ CliRunner import import CliRunner L29–29
+ annotations import import annotations L19–19
+ json import import json L21–21
+ os import import os L22–22
+ pathlib import import pathlib L23–23
+ pytest import import pytest L27–27
+ subprocess import import subprocess L24–24
+ time import import time L25–25
+ runner variable variable runner L31–31
~ muse/cli/commands/bridge.py .py 30 symbols added, 2 symbols modified
+ AttributionMapper class class AttributionMapper L329–383
+ __init__ method method __init__ L345–363
+ get_handle method method get_handle L365–383
+ _ANSI_ESCAPE_RE variable variable _ANSI_ESCAPE_RE L649–649
+ _CatFile class class _CatFile L386–460
+ __enter__ method method __enter__ L456–457
+ __exit__ method method __exit__ L459–460
+ __init__ method method __init__ L405–411
+ close method method close L447–454
+ read method method read L413–445
+ _DEFAULT_EXCLUDE_PREFIXES variable variable _DEFAULT_EXCLUDE_PREFIXES L269–281
+ _DEFAULT_EXCLUDE_SUFFIXES variable variable _DEFAULT_EXCLUDE_SUFFIXES L283–298
+ _batch_commit_log function function _batch_commit_log L482–540
+ _batch_diff_tree function function _batch_diff_tree L543–631
+ _git function function _git L463–479
+ _import_tags function function _import_tags L1056–1108
+ _is_lfs_pointer function function _is_lfs_pointer L634–646
+ _list_git_branches function function _list_git_branches L1007–1020
+ _list_git_tags function function _list_git_tags L1023–1053
+ _parse_sem_ver_bump function function _parse_sem_ver_bump L657–681
+ _replay_branch function function _replay_branch L828–1004
+ _replay_commit function function _replay_commit L684–825
+ _should_exclude function function _should_exclude L301–326
+ _strip_ansi function function _strip_ansi L652–654
+ dataclass class import dataclass L50–50
+ datetime import import datetime L42–42
+ field import import field L50–50
+ hashlib import import hashlib L43–43
+ re import import re L46–46
+ subprocess import import subprocess L47–47
← Older Oldest on task/bridge-phase2
All commits
Newer → Latest on task/bridge-phase2

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