# `muse reflog` — Follow-up Items ## Background Issue #47 delivered complete reflog coverage: all ref-moving operations write entries (commit, checkout, branch-create, merge, reset, rebase, cherry-pick, revert, switch, pull, shelf-pop, shelf-apply), lifecycle management (expire/delete/GC), `@{N}` ref resolution across rev-parse/reset/read/diff/checkout, and a `reflog exists` subcommand. All 30 test IDs (RL_01–RL_30) are green. This issue captures the items explicitly deferred from #47 plus extensions that emerged during implementation. --- ## Deferred from #47 ### 1. Relative time syntax (`@{1.hour.ago}`, `@{yesterday}`) ✅ IMPLEMENTED `@{N}` resolves by index. Git's reflog additionally supports time-based ref syntax: ``` HEAD@{1.hour.ago} → most recent entry older than 1 hour dev@{yesterday} → most recent entry before midnight last night HEAD@{2.days.ago} → 2 days back ``` This is particularly ergonomic for agent prompts: "show me what main looked like an hour ago" is more natural than finding the right index. Implementation lives in `resolve_reflog_ref()` in `muse/core/rev_parse.py` — add a time-spec branch before the integer-index branch. ### 2. `--format` options beyond text/JSON ✅ IMPLEMENTED Currently `muse reflog` outputs human text or `--json`. Two additional formats are useful: - `--format oneline` — `@{N} ` per line, machine-parseable without full JSON overhead. Mirrors `muse log --oneline`. - `--format patch` — each entry followed by the diff it introduced, equivalent to `muse format-patch` output. Useful for generating migration scripts from reflog history. ### 3. Automatic log compaction ✅ IMPLEMENTED Currently reflog files are append-only, pruned only by age (`expire`) or manually (`delete`). For branches with very high churn (e.g. a long-running rebase series with hundreds of fixup commits) the log can grow large before the 90-day window expires. Compaction would merge consecutive entries with the same operation type into a single summary entry — similar to how `muse rebase --squash` works at the commit level. This keeps log files bounded by activity density, not just age. **Decision**: implemented as an explicit `muse reflog compact [--branch ] [--dry-run] [--json]` command rather than an automatic/implicit trigger on `append_reflog`. Reflog entries are the safety-net audit trail for undoing accidental ref movements — silently collapsing history on every write would undermine that guarantee for anyone relying on an un-compacted entry they haven't looked at yet. An explicit, user-invoked (or cron'd) command keeps the same squash semantics available on demand without ever surprising a `muse reflog` read with merged history the caller didn't ask for. ### 4. Remote reflog sharing ✅ IMPLEMENTED Reflogs are currently local-only. For teams on a shared MuseHub remote, a clone has no reflog — a pull starts history from zero. The correct design mirrors the symlog remote sharing plan: - `muse push` optionally bundles `.muse/logs/` alongside commits. - `muse pull` merges incoming reflog entries (append-only, no conflicts). - Per-ref entries are namespaced by remote on the receiving side to avoid collisions. **Implementation**: mirrors the existing version-tags remote-sync precedent (muse#57 item 4) rather than literally embedding reflogs in the content-addressed mpack format, since reflog entries — like version tags — are mutable-pointer-style per-ref metadata, not content-addressed objects: - `muse push --reflog` (or `push.reflog=true` config) sends this branch's local reflog entries via `POST {url}/reflog?branch=`, oldest-first. - `muse pull` always best-effort fetches via `GET {url}/reflog?branch=` and merges incoming entries into `.muse/logs/refs/remotes//` — **never** into the local branch's own reflog (`refs/heads/`), exactly mirroring git's own separation between a branch's reflog and its remote-tracking ref's reflog. This is what "namespaced by remote" means in practice. - Merging is idempotent (compares exact raw line content) and append-only — genuinely "no conflicts," since reflog entries are immutable history. - `muse reflog --remote --branch ` reads the merged remote-tracking log back. - Server side (MuseHub): new `musehub_reflog_entries` table, keyed by a content-hash `entry_id` (not a mutable `(repo_id, branch)` pointer like version tags) so re-pushing an already-stored entry is a true `ON CONFLICT DO NOTHING` no-op — there is nothing to conflict, unlike a tag that can legitimately re-point to a different commit. ### 5. Reflog for tags ✅ IMPLEMENTED The current implementation writes entries for branch refs (`refs/heads/*`) only. `muse tag add` and `muse release add` move `refs/tags/*` without a trace. A `muse reflog --tag v1.0.0` command should show the tag creation and any subsequent re-tagging events. --- ## New items from implementation ### 6. `muse reflog stat [--branch ] [--json]` ✅ IMPLEMENTED Summary statistics for a branch reflog: total entries, operation breakdown (commit/reset/merge/rebase/…), most active author, first and last timestamps, number of resets (indicator of how often the branch was "undone"). Useful context for agents deciding whether a branch is stable enough to merge. ### 7. `muse reflog diff @{N} @{M} [--json]` ✅ IMPLEMENTED Currently `muse diff @{N} HEAD` works. But diffing two arbitrary reflog states requires manual SHA resolution. A dedicated `muse reflog diff @{N} @{M}` command makes point-in-time comparisons first-class, resolving both specs from the same branch's reflog automatically. ### 8. `muse reflog anchor [--json]` ✅ IMPLEMENTED Given a commit ID, return all `@{N}` indices (across all branches) where that commit appears in the reflog. Answers: "how did I get to this commit, and from how many different paths?" Useful for post-mortem analysis of complex rebase sequences. ### 9. Reflog entries for `muse worktree add` / `muse worktree remove` ✅ IMPLEMENTED Creating or removing a linked worktree moves refs but leaves no reflog trace. These operations should append entries to the worktree's HEAD log so the full ref history is preserved regardless of which worktree triggered the move. ### 10. `muse reflog watch [--branch ] [--json]` ✅ IMPLEMENTED Stream reflog entries as they are written — a live tail of ref movements. Useful for agents monitoring a long-running operation (e.g. an automated rebase series) without polling `muse reflog --json` in a loop.