Re: `git push --porcelain` has no effect when deleting a ref which does not exist
Looking at the current code, the abort when requesting the deletion of a ref which is not on the remote is pretty early in the process, during ref matching, which then causes `push` to bail.
Reading some of the followup the following call `set_ref_status_for_push` can already set statuses on remote refs before the push, in which case such refs with statuses set will be ignored for the actual network operation (and the entire thing would be skipped if atomic), and then we get to the reporting and teardown.
So it looks like
- `match_explicit` could create a dummy dest ref and set its status to
some sort of failure value (either an existing one or a new one) instead
of aborting
- then `set_ref_status_for_push` should skip over refs which already
have a status set (so it doesn't overwrite a previous error)
- push_refs_with_push all refs with a rejection status already set
- and then the formatting needs to get adapted for the new mode / case
And then trying to delete a non-existent ref would appear in the report normally, and valid pushes would be performed instead of ignored, unless `atomic` was set in which case they'd all be aborted, similar to other abortions from "pre-push" checks by set_ref_status_for_push.
Does that seem to make sense or did I miss something critical? Do you foresee significant issues?
Would you rather a new status code for this case or extending an existing case? e.g. I could see REF_STATUS_REJECT_NODELETE on an otherwise zeroed deletion ref for missing on remote, and a non-zeroed deletion ref would be the existing "remote rejecting the deletion" case so less code (and notably not push_refs_with_push) would have to be adapted, but it would make the new case a bit more implicit.