/simplify: tidy rewrite (resolveAuthor, thread refName, sparse tasks graft) · Entire
/simplify: tidy rewrite (resolveAuthor, thread refName, sparse tasks graft)
b24e3ba·
Soph·1w ago·2 files·+79 added/-46 removed
- Collapse the fallback name/email into a commitAuthor and extract resolveAuthor, shrinking rewriteCheckpoint's parameter list and de-duplicating the per-session and tasks-graft author fallback.
- Compute the ref name once in the walk and thread it through rewriteCheckpoint and graftTasksSubtree instead of recomputing RefName three times per checkpoint.
- Graft tasks with a single UpdateSubtree(MergeKeepExisting) call — splicing the tasks/ entry into the root tree so sibling session subtrees keep their hashes — instead of flattening and rebuilding the whole tree.
- Reset the ref only under --force (the non-force existing-ref case is already skipped by the caller), dropping a redundant check.
- Add a graft test covering the tasks splice (tasks/ added, existing entries preserved, checkpoint still reads back).
Sessions
48ce721ba1a2View transcript
Changes
2
cmd/entire/cli/checkpoint
Mrewrite.go+41/-46
Mrewrite_test.go+38
54 unmodified lines
// tasksDirName is the checkpoint subtree that holds subagent task steps. const tasksDirName = "tasks";
// commitAuthor is a git author identity. type commitAuthor struct { Name string Email string }
// resolveAuthor returns the recorded author for a session, or the fallback when // the session has no mapped commit author. func resolveAuthor(sessionID string, authors map[string]commitAuthor, fallback commitAuthor) commitAuthor { if a, ok := authors[sessionID]; ok && a.Name != "" { return a } return fallback }
// branchSessionAuthors maps each session id to the author of the earliest // v1-branch commit that wrote it, so a rewrite can preserve the original author. // The map is best-effort: a session with no resolvable commit falls back to the // existing author. refsStore *gitRefsStore, repo *git.Repository, cid id.CheckpointID, refName plumbing.ReferenceName, cpTreeHash plumbing.Hash, authors map[string]commitAuthor, fallbackName, fallbackEmail string, fallback commitAuthor, force bool, ) error {
// Start clean: drop any existing ref so the replay builds a fresh history // rooted at an orphan commit rather than parenting on stale content. refName, err := RefName(cid) if err != nil { return err } if _, err := repo.Reference(refName, true); err == nil { if err := repo.Storer.RemoveReference(refName); err != nil { return fmt.Errorf("reset existing ref: %w", err) } }
// Replay each session in order. Writing session N then its summary keeps // SessionSummary (which targets the latest session) pointed at the right one. for idx := range summary.Sessions { content, err := branch.ReadSessionContent(ctx, cid, idx) if err != nil { return fmt.Errorf("read session %d: %w", idx, err) } m := content.Metadata name, email := fallbackName, fallbackEmail author := resolveAuthor(m.SessionID, authors, fallback)
if err := refsStore.Write(ctx, Session(WriteOptions{ AuthorName: name, AuthorEmail: email, AuthorName: author.Name, AuthorEmail: author.Email, Agent: m.Agent, Model: m.Model, TurnID: m.TurnID, })); err != nil { return fmt.Errorf("write session: %w", err) } }
return nil }
// graftTasksSubtree adds the tasks/ subtree to the checkpoint's current ref tree // via one commit on top, reusing the existing task objects unchanged. func graftTasksSubtree(ctx context.Context, repo *git.Repository, refsStore *gitRefsStore, cid id.CheckpointID, tasksHash plumbing.Hash, author commitAuthor) error { refName, err := RefName(cid) if err != nil { return err } // additional implementation details... }