Artifact 549bab84e2546401650ee634c07c6af2eca5c8f2a6d03f0030082f8d94559935:
- File
cli/repo_timeline.go
— part of check-in
[ee3ccc7c67]
at
2026-10-22 17:21:12
on branch feat/horizon-cones
— feat(history): render a horizon boundary as the horizon
A parent the origin labelled below a structural horizon is the horizon itself (draft-fossil-horizon-00 5.4), but the history views showed it as a bare parent hash, and the ancestry walk tried to read an event for it.
LogEntry and TimelineEntry gain HorizonParents, the subset of Parents that carries a boundary label; Ancestry ends at such a parent without an error; repo timeline prints it as "parent: <hash> (horizon)". An absent parent that is not labelled is transit and renders as before. (user: [email protected], size: 1284) [annotate] [blame] [check-ins using] [more...]
package cli import ( "fmt" libfossil "github.com/danmestas/go-libfossil" ) // RepoTimelineCmd shows repository timeline/history. type RepoTimelineCmd struct { Limit int `short:"n" default:"20" help:"Number of entries"` } func (c *RepoTimelineCmd) Run(g *Globals) error { r, err := g.OpenRepo() if err != nil { return err } defer r.Close() entries, err := r.Timeline(libfossil.TimelineOpts{Limit: c.Limit}) if err != nil { return err } for _, e := range entries { uuid := e.UUID if len(uuid) > 10 { uuid = uuid[:10] } // A check-in with no recorded user (event.user IS NULL) comes back // from the library as "" — TimelineEntry.User never leaks a nullable type. // Canonical fossil renders that case as "?" on the TTY // (coalesce(euser,user,'?') in timeline_query_for_tty()); match it // here at the presentation boundary rather than in the library. user := e.User if user == "" { user = "?" } fmt.Printf("%s %s %s %s\n", uuid, e.Time.Format("2006-01-02 15:04"), user, e.Comment) // A parent the origin labelled below a structural horizon is the // horizon itself, not a missing parent (draft-fossil-horizon-00 §5.4). for _, p := range e.HorizonParents { fmt.Printf(" parent: %s (horizon)\n", p) } } return nil }