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:

Sessions

9e819d18460e View transcript

Changes

3

//   - 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:

  1. Under the cap emits no note.
  2. Budget hit reports truncated and caps the slice.
  3. Exactly at the cap emits no note.
  4. Budget exactly met reports no truncation.
  5. Over the cap trims and notes truncation.
  6. Budget exceeds count reports no truncation.