Verify, before a push begins, that the client can produce credentials for `remote_url`. Fails fast with an actionable error instead of letting the push proceed into a confusing 404 (which the server returns for private projects the caller isn't authorized to see). Returns `Ok(())` when an identity is resolvable (from `--identity`, the URL, or the default identity), exists in the local store, and
(remote_url: &str, identity_override: Option<&str>)
| 418 | /// `--identity` explicitly names an identity that doesn't exist — that is a |
| 419 | /// clear error, not a silent substitution. |
| 420 | pub fn check_push_credentials(remote_url: &str, identity_override: Option<&str>) -> CliResult<()> { |
| 421 | let store = IdentityStore::open_default() |
| 422 | .map_err(|e| CliError::Internal(anyhow::anyhow!("Failed to open identity store: {e}")))?; |
| 423 | |
| 424 | let inferred = resolve_identity_name_with_override(remote_url, identity_override); |
| 425 | let explicit = identity_override.is_some(); |
| 426 | |
| 427 | // Resolve a concrete identity, falling back to the default when the |
| 428 | // inferred name doesn't match (and the name didn't come from --identity). |
| 429 | let identity = |
| 430 | resolve_identity_with_default_fallback(&store, inferred.as_deref(), explicit, "push"); |
| 431 | let resolved_name = identity.as_ref().map(|id| id.name.clone()); |
| 432 | |
| 433 | let issue = evaluate_push_credentials( |
| 434 | explicit, |
| 435 | inferred.as_deref(), |
| 436 | resolved_name.as_deref(), |
| 437 | |name| { |
| 438 | load_identity_lenient(&store, name) |
| 439 | .map(|id| store.load_keypair(&id.id, None).is_ok()) |
| 440 | .unwrap_or(false) |
| 441 | }, |
| 442 | ); |
| 443 | |
| 444 | match issue { |
| 445 | Some(issue) => Err(CliError::AuthenticationFailed { |
| 446 | remote: format!("{remote_url}: {}", issue.message()), |
| 447 | }), |
| 448 | None => Ok(()), |
| 449 | } |
| 450 | } |
| 451 | |
| 452 | /// Pure decision core for [`check_push_credentials`], split out so it can be |
| 453 | /// unit-tested without touching the on-disk identity store. |
no test coverage detected