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>)
| 465 | /// `--identity` explicitly names an identity that doesn't exist — that is a |
| 466 | /// clear error, not a silent substitution. |
| 467 | pub fn check_push_credentials(remote_url: &str, identity_override: Option<&str>) -> CliResult<()> { |
| 468 | let store = IdentityStore::open_default() |
| 469 | .map_err(|e| CliError::Internal(anyhow::anyhow!("Failed to open identity store: {e}")))?; |
| 470 | |
| 471 | let inferred = resolve_identity_name_with_override(remote_url, identity_override); |
| 472 | let explicit = identity_override.is_some(); |
| 473 | |
| 474 | // Resolve a concrete identity, falling back to the default when the |
| 475 | // inferred name doesn't match (and the name didn't come from --identity). |
| 476 | let identity = |
| 477 | resolve_identity_with_default_fallback(&store, inferred.as_deref(), explicit, "push"); |
| 478 | let resolved_name = identity.as_ref().map(|id| id.name.clone()); |
| 479 | |
| 480 | let issue = evaluate_push_credentials( |
| 481 | explicit, |
| 482 | inferred.as_deref(), |
| 483 | resolved_name.as_deref(), |
| 484 | |name| { |
| 485 | load_identity_lenient(&store, name) |
| 486 | .map(|id| store.load_keypair(&id.id, None).is_ok()) |
| 487 | .unwrap_or(false) |
| 488 | }, |
| 489 | ); |
| 490 | |
| 491 | match issue { |
| 492 | Some(issue) => Err(CliError::AuthenticationFailed { |
| 493 | remote: format!("{remote_url}: {}", issue.message()), |
| 494 | }), |
| 495 | None => Ok(()), |
| 496 | } |
| 497 | } |
| 498 | |
| 499 | /// Pure decision core for [`check_push_credentials`], split out so it can be |
| 500 | /// unit-tested without touching the on-disk identity store. |
no test coverage detected