gabriel / muse public
feat patch reflog task/reflog-phase1 #3 / 8
AI Agent gabriel · 22 days ago · Jun 28, 2026 · Diff

feat(reflog): Phase 5 — @{N} ref resolution (RL_21–RL_27)

- Add resolve_reflog_ref(spec, repo_root) to muse/core/reflog.py - Accepts @{N}, branch@{N}, refs/heads/branch@{N} - Returns new_id from the matching reflog entry (newest-first index) - Raises FileNotFoundError when log file missing - Raises IndexError(index, total) when index out of range - Inject @{N} resolution into resolve_commit_ref in muse/core/commits.py - Checked before tilde/branch/SHA resolution - Returns None on FileNotFoundError or IndexError (callers emit USER_ERROR) - Enables: muse reset @{N}, muse read @{N}, muse diff @{N} HEAD - Inject @{N} resolution into muse rev-parse with USER_ERROR messages (RL_25) - FileNotFoundError → 'no reflog for this ref' - IndexError → '@{N} out of range; valid range: 0–M' - 33 new tests; 133/133 across all reflog+GC test files; 44 rev-parse tests green

sha256:c954eb58546fafefa25622da689a6cd146a5a4efa32601a3ba81cd30620e74e8 sha
+64 ~2 symbols
sha256:b5ab2a9cdc386d8164f1f4e549833bc306b936a55c029bf1680a2e538bbe619c snapshot
+64
symbols added
~2
symbols modified
0
dead code introduced
Semantic Changes 66 symbols
~ tests/test_reflog_ref_resolution.py .py 61 symbols added
+ TestAtNOutOfRange class class TestAtNOutOfRange L332–379
+ test_branch_at_n_out_of_range method method test_branch_at_n_out_of_range L374–379
+ test_no_log_file_gives_user_error method method test_no_log_file_gives_user_error L366–372
+ test_out_of_range_error_mentions_valid_range method method test_out_of_range_error_mentions_valid_range L344–355
+ test_out_of_range_reset_exits_user_error method method test_out_of_range_reset_exits_user_error L357–364
+ test_out_of_range_rev_parse_exits_user_error method method test_out_of_range_rev_parse_exits_user_error L335–342
+ TestBranchAtN class class TestBranchAtN L277–325
+ test_branch_at_one_resolves_via_branch_log method method test_branch_at_one_resolves_via_branch_log L289–296
+ test_branch_at_zero_resolves_to_newest method method test_branch_at_zero_resolves_to_newest L280–287
+ test_head_log_and_branch_log_resolve_independently method method test_head_log_and_branch_log_resolve_independently L310–325
+ test_refs_heads_prefix_form_accepted method method test_refs_heads_prefix_form_accepted L298–308
+ TestDiffAtN class class TestDiffAtN L386–432
+ test_diff_at_one_head_exits_zero method method test_diff_at_one_head_exits_zero L389–396
+ test_diff_at_one_head_has_required_json_fields method method test_diff_at_one_head_has_required_json_fields L398–409
+ test_diff_at_one_head_shows_changes method method test_diff_at_one_head_shows_changes L411–421
+ test_diff_at_zero_head_is_empty method method test_diff_at_zero_head_is_empty L423–432
+ TestEndToEndRecovery class class TestEndToEndRecovery L439–495
+ test_message_at_restored_commit_is_correct method method test_message_at_restored_commit_is_correct L464–474
+ test_reset_at_one_restores_previous_commit method method test_reset_at_one_restores_previous_commit L442–462
+ test_rev_parse_after_reset_shows_old_id method method test_rev_parse_after_reset_shows_old_id L476–485
+ test_three_commit_chain_recovery method method test_three_commit_chain_recovery L487–495
+ TestReadAtN class class TestReadAtN L243–270
+ test_read_at_n_shows_correct_message method method test_read_at_n_shows_correct_message L264–270
+ test_read_at_two_shows_oldest_commit method method test_read_at_two_shows_oldest_commit L255–262
+ test_read_at_zero_shows_newest_commit method method test_read_at_zero_shows_newest_commit L246–253
+ TestResetAtN class class TestResetAtN L205–236
+ test_branch_ref_advances_after_reset method method test_branch_ref_advances_after_reset L226–236
+ test_reset_at_one_moves_to_second_commit method method test_reset_at_one_moves_to_second_commit L208–215
+ test_reset_at_two_moves_to_oldest_commit method method test_reset_at_two_moves_to_oldest_commit L217–224
+ TestResolveReflogRefUnit class class TestResolveReflogRefUnit L502–554
+ test_branch_spec_reads_branch_log method method test_branch_spec_reads_branch_log L540–546
+ test_raises_file_not_found_when_no_log method method test_raises_file_not_found_when_no_log L521–527
+ test_raises_index_error_out_of_range method method test_raises_index_error_out_of_range L529–538
+ test_refs_heads_prefix_stripped method method test_refs_heads_prefix_stripped L548–554
+ test_returns_new_id_for_valid_index method method test_returns_new_id_for_valid_index L513–519
+ test_returns_none_for_non_at_spec method method test_returns_none_for_non_at_spec L505–511
+ TestRevParseAtN class class TestRevParseAtN L162–198
+ test_at_one_resolves_to_second_newest method method test_at_one_resolves_to_second_newest L175–182
+ test_at_zero_resolves_to_newest_commit method method test_at_zero_resolves_to_newest_commit L165–173
+ test_at_zero_text_mode_prints_commit_id method method test_at_zero_text_mode_prints_commit_id L184–190
+ test_ref_field_echoes_at_spec method method test_ref_field_echoes_at_spec L192–198
+ _branch_log function function _branch_log L43–44
+ _env function function _env L35–36
+ _head_log function function _head_log L39–40
+ _make_base_repo function function _make_base_repo L105–118
+ _make_commit function function _make_commit L61–97
+ _set_branch function function _set_branch L100–102
+ _setup_repo_with_history function function _setup_repo_with_history L121–155
+ _write_reflog_entry function function _write_reflog_entry L47–58
+ cli variable variable cli L29–29
+ CliRunner import import CliRunner L26–26
+ NULL_COMMIT_ID import import NULL_COMMIT_ID L25–25
+ annotations import import annotations L15–15
+ datetime import import datetime L17–17
+ json import import json L18–18
+ logs_dir import import logs_dir L24–24
+ muse_dir import import muse_dir L24–24
+ pathlib import import pathlib L19–19
+ pytest import import pytest L22–22
+ time import import time L20–20
+ runner variable variable runner L28–28
~ muse/cli/commands/rev_parse.py .py 1 symbol modified
~ run
~ muse/core/commits.py .py 1 symbol modified
~ muse/core/reflog.py .py 3 symbols added
+ _AT_N_RE variable variable _AT_N_RE L439–441
+ re import import re L55–55
+ resolve_reflog_ref function function resolve_reflog_ref L444–497

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