gitproto: classify target-ref moves by extracting CommandStatusErr robustly

main

Commit

nodo2mo ago

asRefRejectedError and annotateLeaseFailure used errors.As against a *packp.CommandStatusErr (pointer) target, but go-git returns CommandStatusErr BY VALUE from ReportStatus.Error() (value receiver, constructed by value in report_status.go). A pointer target never matches a value in the error chain, so on the real receive-pack path the errors.As fell through, no *RefRejectedError was built, moved was never set, and errors.Is(err, ErrTargetRefMoved) was always false. Every live concurrent target-ref rejection ("remote ref has changed") passed through unclassified — the typed-rejection feature was inert in production. The same bug silently disabled the lease-failure hint.

Extract the error through a shared commandStatusErr helper that accepts BOTH the value form (today's go-git) and a *CommandStatusErr, since errors.As is exact about value-vs-pointer and the form is not part of go-git's (alpha) API contract — so a future switch can't silently regress classification to "every rejection unclassified".

The existing unit tests masked the original bug by feeding a pointer &packp.CommandStatusErr{} as input, which the pointer target did match — not how go-git hands the error over. Make the table tests build input via go-git's real (&CommandStatus{}).Error() (value), add TestAsRefRejectedError_RealReportStatusPath (drives a real ReportStatus.Error() end to end; fails loud on a deeper type change) and TestAsRefRejectedError_ToleratesPointerCommandStatusErr (pins the pointer form).

Bug was in the unreleased typed-rejection feature (#71); never shipped tagged.

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

Checkpoints

can you review https://github.com/entirehq/mirror-pipeline/pull/135

Claude CodeOpus 4.8
View session
Checkpoint 1