gabriel / muse public
feat patch feat/54-reflog-time-syntax #1 / 1
AI Agent gabriel · 8 hours ago · Oct 21, 2026 · Diff

feat: muse#54 item 1 — relative time syntax for @{...} reflog refs

Extends resolve_reflog_ref() to accept relative-time specs alongside the existing @{N} integer-index form:

- @{N.unit.ago} — unit is second/minute/hour/day/week, singular or plural (e.g. "1.hour.ago", "2.days.ago"). - @{yesterday} — start of today (UTC midnight), i.e. "most recent entry before midnight last night".

Both forms resolve to the most recent entry at or before the computed cutoff, scoped to HEAD or a named branch log exactly like the existing @{N} / branch@{N} forms. The @{N} regex was broadened from a digits-only capture to a generic "anything inside the braces" capture, then disambiguated inside resolve_reflog_ref: digit-only -> index path (unchanged behavior), otherwise -> time-spec path. Unrecognized specs and specs where no entry is old enough both return None, same contract as "spec doesn't match the @{N} pattern" — callers (rev-parse, checkout, diff, resolve_commit_ref) already treat a None/exception result as "try the next resolution strategy," so no caller changes were needed.

Covered by tests/test_reflog_time_resolution.py (8 cases: hour-ago cutoff selection, minutes-ago, yesterday, no-entry-old-enough, named-branch time spec, unrecognized spec, non-regression of the plain @{N} index form, and a `muse rev-parse` CLI integration test). Confirmed genuine RED by reverting the fix file and re-running (5 of 8 failed — the time-spec-specific cases — while the 3 unaffected-behavior cases passed incidentally), then GREEN with the fix restored. Ran the full targeted regression suite (346 tests across every reflog/rev-parse/ checkout test file) with zero regressions. Live-verified via muse-dev against a disposable /tmp sandbox (0.second.ago, yesterday, and 1.week.ago with no qualifying entry).

Co-Authored-By: Claude Sonnet 5 <[email protected]>

sha256:2d36521a1c0daf8222df46cff206eb4d8a12b8f22bc71dfa5d7011c5e47ad169 sha
+34 ~5 symbols
3 changed · 1228 in snapshot files
sha256:76cfd0bf962f85685a996b9f842c3ccc21cf4bbccb2b3077ba29e150655737f5 snapshot
+34
symbols added
~5
symbols modified
3
files changed
1228
files in snapshot
0
dead code introduced
Semantic Changes 39 symbols
~ tests/test_reflog_time_resolution.py .py 31 symbols added
+ TestTimeAgoResolution class class TestTimeAgoResolution L61–147
+ test_hour_ago_finds_entry_before_cutoff method method test_hour_ago_finds_entry_before_cutoff L62–76
+ test_minutes_ago_finds_most_recent_entry method method test_minutes_ago_finds_most_recent_entry L78–91
+ test_named_branch_time_spec method method test_named_branch_time_spec L117–125
+ test_no_entry_old_enough_returns_none method method test_no_entry_old_enough_returns_none L107–115
+ test_plain_index_still_works method method test_plain_index_still_works L137–147
+ test_unrecognized_spec_returns_none method method test_unrecognized_spec_returns_none L127–135
+ test_yesterday_finds_entry_before_todays_midnight method method test_yesterday_finds_entry_before_todays_midnight L93–105
+ TestTimeAgoViaCli class class TestTimeAgoViaCli L150–163
+ test_rev_parse_accepts_time_spec method method test_rev_parse_accepts_time_spec L151–163
+ _env function function _env L25–26
+ _fake_commit_id function function _fake_commit_id L57–58
+ _init_repo function function _init_repo L33–46
+ _run function function _run L29–30
+ _write_raw_entry function function _write_raw_entry L49–54
+ cli variable variable cli L21–21
+ CliRunner import import CliRunner L16–16
+ Manifest import import Manifest L17–17
+ NULL_COMMIT_ID import import NULL_COMMIT_ID L17–17
+ annotations import import annotations L8–8
+ datetime import import datetime L10–10
+ fake_id import import fake_id L17–17
+ json import import json L11–11
+ logs_dir import import logs_dir L18–18
+ muse_dir import import muse_dir L18–18
+ pathlib import import pathlib L12–12
+ pytest import import pytest L14–14
+ reflog_branch_path import import reflog_branch_path L18–18
+ reflog_heads_dir import import reflog_heads_dir L18–18
+ resolve_reflog_ref import import resolve_reflog_ref L19–19
+ runner variable variable runner L22–22
~ muse/core/reflog.py .py 3 symbols added, 2 symbols modified
+ _TIME_AGO_RE variable variable _TIME_AGO_RE L530–532
+ _TIME_UNIT_SECONDS variable variable _TIME_UNIT_SECONDS L534–536
+ _parse_time_cutoff function function _parse_time_cutoff L539–560
Files Changed
+1 ~2
1228 in snapshot
← Older Oldest on feat/54-reflog-time-syntax
All commits
Newer → Latest on feat/54-reflog-time-syntax

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