explain: fix branch-list truncation detection and note wording · Entire
Explain: Fix branch-list truncation detection and note wording
32495e3→main
Addresses PR #1560 review:
- Detect truncation at its source:
getBranchCheckpointsnow returns whether it hit its scan budget, instead of guessing from the returned slice length (which over-triggered and, worse, dropped checkpoints — the live and imported budgets are independent, so the list can hold up to 2*limit entries with nothing actually dropped). - Prose branch list renders everything returned (restoring pre-PR behavior) and only notes truncation when the budget was genuinely hit.
- Truncation note names the full
entire checkpoint explain --json --limit <N>command, valid whether reached via explain, checkpoint explain, or checkpoint list (which has no --json flag of its own). - Note wording is budget-based, not display-count based, so a --session filter no longer skews it; no exact count is claimed.
- JSON list path uses the same source-of-truth truncation signal.
Sessions
9e819d18460e View transcript
Changes
3
- cmd/entire/cli
- Mexplain.go +34/-28
- Mexplain_export.go +11/-9
- Mexplain_test.go +65/-38
// - On feature branches: only show checkpoints unique to this branch (not in main)
// - On default branch (main/master): show all checkpoints in history (up to limit)
// - Includes both committed checkpoints (entire/checkpoints/v1) and temporary checkpoints (shadow branches)
func getBranchCheckpoints(ctx context.Context, repo *git.Repository, limit int) ([]strategy.RewindPoint, error) {
// The second return value is true when either the live (commit-linked +
// temporary) or imported budget hit `limit`, i.e. older checkpoints were
// dropped. This is the authoritative truncation signal: the budgets are
// applied here, so callers cannot reconstruct it from the returned length
// (the two budgets are independent, so the slice can hold up to 2*limit
// entries without anything being dropped).
func getBranchCheckpoints(ctx context.Context, repo *git.Repository, limit int) ([]strategy.RewindPoint, bool, error) {
// Warn (once per process) if metadata branches are disconnected
strategy.WarnIfMetadataDisconnected()
stores, err := checkpoint.Open(ctx, repo, checkpoint.OpenOptions{})
if err != nil {
return nil, fmt.Errorf("open checkpoint store: %w", err)
}
store := stores.Persistent
if err != nil {
// Unborn HEAD (no commits yet) - return empty list instead of erroring
if errors.Is(err, plumbing.ErrReferenceNotFound) {
return []strategy.RewindPoint{}, nil
}
return nil, fmt.Errorf("failed to get HEAD: %w", err)
}
// Check if we're on the default branch (needed for getReachableTemporaryCheckpoints)
tempPoints := getReachableTemporaryCheckpoints(ctx, repo, stores.Ephemeral(), head.Hash(), isOnDefault, limit)
points = append(points, tempPoints...)
truncated := false
// Sort live points (commit-linked + temporary) and apply the limit FIRST, so
// a large historical import can't evict recent commit-linked checkpoints.
sort.Slice(points, func(i, j int) bool {
})
if len(points) > limit {
points = points[:limit]
truncated = true
}
// Append imported (read-only, commit-less) checkpoints after the live points,
return points, nil
}
}
Testing for the checking of truncation and various behaviors of the getBranchCheckpoints involved checking conditions on different branches and making sure it returns the correct number of checkpoints.
Several test scenarios were run to ensure functionality:
- Under the cap emits no note.
- Budget hit reports truncated and caps the slice.
- Exactly at the cap emits no note.
- Budget exactly met reports no truncation.
- Over the cap trims and notes truncation.
- Budget exceeds count reports no truncation.