errors: address review — nil-safe Error, lease-path sentinel, doc caveats

main

Commit

nodo3mo ago

Follow-up to review feedback on the ErrTargetRefMoved / RefRejectedError API:

  • RefRejectedError.Error() no longer nil-panics on an externally-constructed value (exported Ref/Reason, unexported err): it falls back to a formatted "ref X rejected: reason". Embedders can now build &RefRejectedError{...} in their own errors.As tests. Documented that the move classification can't be reproduced externally (moved is unexported) and to wrap the sentinel directly to exercise errors.Is.

  • The BestEffort + ForceWithLease lease-failure escalation now also satisfies errors.Is(err, ErrTargetRefMoved) by wrapping the sentinel. Under explicit ForceWithLease the "ambiguous marker" caveat doesn't apply — the caller opted into lease semantics — so a lease miss there is definitionally a target move. Public doc notes this path is not itself a *RefRejectedError (prefer errors.Is over errors.As when you only need the cause).

  • Documented that concurrentMoveMarkers is server-specific by design: "remote ref has changed" is entire-server's CAS reason (the case that matters); "stale info" is git's client-side force-with-lease phrasing kept for consistency; stock git servers phrase CAS misses differently ("failed to update ref" / "cannot lock ref ...") and are intentionally not matched. Extend as new server phrasings are observed.

  • Documented that RefRejectedError reflects the first rejected ref when a push rejects several (report-status surfaces the first, per canonical git).

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com