diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-01-23 09:18:13 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-01-23 09:18:13 +0000 |
| commit | 9fd4350c57bbe986ebf65bf3ea4c996572e81884 (patch) | |
| tree | 4002e04712495b2999a9f14612634b796aebbf1e /src/purgatory/sync | |
| parent | 22c9ccd8f17815c960e797a545ab3cb1385ffcf8 (diff) | |
fix: improve 'not our ref' error messages and warn about multi-OID fetch bug
When git fetch fails with 'upload-pack: not our ref', git stops at the first
missing OID and doesn't attempt to fetch remaining OIDs. This means if we
request 5 OIDs and the first is missing, we never try the other 4 (which may
exist on the remote).
Changes:
- Parse missing OID from stderr for clearer error messages
- Single OID case: 'remote missing only oid requested: <oid>'
- Multi OID case: Log WARNING and indicate other OIDs weren't attempted
- Identifies the bug that needs retry logic to fetch OIDs individually
Diffstat (limited to 'src/purgatory/sync')
| -rw-r--r-- | src/purgatory/sync/context.rs | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/src/purgatory/sync/context.rs b/src/purgatory/sync/context.rs index f41dc25..33c2d12 100644 --- a/src/purgatory/sync/context.rs +++ b/src/purgatory/sync/context.rs | |||
| @@ -408,7 +408,45 @@ impl SyncContext for RealSyncContext { | |||
| 408 | } | 408 | } |
| 409 | } | 409 | } |
| 410 | 410 | ||
| 411 | Err(anyhow::anyhow!("git fetch failed: {}", stderr)) | 411 | // Check for "not our ref" errors and provide a clearer error message |
| 412 | let error_msg = if stderr.contains("upload-pack: not our ref") { | ||
| 413 | // Parse out the missing OID from stderr (git only reports one at a time) | ||
| 414 | let missing_oid = stderr | ||
| 415 | .lines() | ||
| 416 | .find_map(|line| { | ||
| 417 | if line.contains("not our ref") { | ||
| 418 | // Extract the OID from lines like: | ||
| 419 | // "fatal: remote error: upload-pack: not our ref <oid>" | ||
| 420 | line.split("not our ref").nth(1).map(|s| s.trim().to_string()) | ||
| 421 | } else { | ||
| 422 | None | ||
| 423 | } | ||
| 424 | }); | ||
| 425 | |||
| 426 | let total_requested = missing_oids.len(); | ||
| 427 | |||
| 428 | if let Some(oid) = missing_oid { | ||
| 429 | if total_requested > 1 { | ||
| 430 | // BUG: Git stops at first missing OID, so we don't know if the others exist | ||
| 431 | // We need retry logic to fetch remaining OIDs individually | ||
| 432 | tracing::warn!( | ||
| 433 | url = %url, | ||
| 434 | missing_oid = %oid, | ||
| 435 | total_requested = total_requested, | ||
| 436 | "Git fetch failed on first missing OID - other requested OIDs may exist but were not fetched. Retry logic needed." | ||
| 437 | ); | ||
| 438 | format!("remote missing oid {} (BUG: {} other oids not attempted)", oid, total_requested - 1) | ||
| 439 | } else { | ||
| 440 | format!("remote missing only oid requested: {}", oid) | ||
| 441 | } | ||
| 442 | } else { | ||
| 443 | format!("git fetch failed: {}", stderr) | ||
| 444 | } | ||
| 445 | } else { | ||
| 446 | format!("git fetch failed: {}", stderr) | ||
| 447 | }; | ||
| 448 | |||
| 449 | Err(anyhow::anyhow!("{}", error_msg)) | ||
| 412 | } | 450 | } |
| 413 | Err(e) => Err(anyhow::anyhow!("git fetch command error: {}", e)), | 451 | Err(e) => Err(anyhow::anyhow!("git fetch command error: {}", e)), |
| 414 | } | 452 | } |