Artifact f8892069bf34d245b40721a059f41f784d95b61c4d597ba597f6365edd4be186:
- File
cli/repo_log.go
— part of check-in
[beed361c03]
at
2026-10-19 20:17:37
on branch feat/cli-snapshot
— feat(cli): checkout-free snapshot, per-path log, cat --at and diff --json
repo snapshot commits one file's bytes onto trunk with no checkout, a no-op when they equal the tip. repo log --path lists the check-ins that changed a path, repo cat --at reads a file as a version holds it, and repo diff --json A B [PATH] diffs two versions. Exit 2 means not found. A snapshot re-checks the check-in stamp inside its write transaction and retries, so concurrent processes build one linear trunk.
Tracked in #451 (user: [email protected], size: 1883) [annotate] [blame] [check-ins using] [more...]
package cli import ( "database/sql" "errors" "fmt" "github.com/danmestas/go-libfossil/internal/manifest" ) // RepoLogCmd lists the check-ins that changed one path, newest first, as // fossil finfo does. type RepoLogCmd struct { Path string `required:"" help:"File name in the repository"` JSON bool `help:"Print a JSON array instead of text"` Limit int `short:"n" help:"Number of entries (default: all)"` } // logEntry is one element of log's --json array. type logEntry struct { UUID string `json:"uuid"` Time string `json:"time"` User string `json:"user"` Comment string `json:"comment"` Action string `json:"action"` FileUUID string `json:"file_uuid,omitempty"` PrevName string `json:"prev_name,omitempty"` } // jsonTime is the time format of every JSON field: RFC 3339, UTC, with // milliseconds, the precision a check-in records. const jsonTime = "2006-01-02T15:04:05.000Z" func (c *RepoLogCmd) Run(g *Globals) (err error) { r, err := g.OpenRepo() if err != nil { return err } defer func() { if cerr := r.Close(); cerr != nil && err == nil { err = cerr } }() versions, err := manifest.FileHistory(r.Inner(), manifest.FileHistoryOpts{ Path: c.Path, Limit: c.Limit, }) if errors.Is(err, sql.ErrNoRows) || err == nil && len(versions) == 0 { return notFound(fmt.Errorf("no history for %q", c.Path)) } if err != nil { return err } entries := make([]logEntry, len(versions)) for i, v := range versions { entries[i] = logEntry{ UUID: v.CheckinUUID, Time: v.Date.UTC().Format(jsonTime), User: v.User, Comment: v.Comment, Action: v.Action.String(), FileUUID: v.FileUUID, PrevName: v.PrevName, } } if c.JSON { return writeJSON(entries) } for _, e := range entries { fmt.Printf("%s %s %s %s %s\n", e.UUID[:10], e.Time, e.User, e.Action, e.Comment) } return nil }