mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-05 15:08:24 +00:00
fix: accept no-op pushes where old_oid == new_oid
Fixes race condition where user's push becomes no-op after state event is applied between fetch and push. Now accepts these as successful no-ops, matching Git's 'Everything up-to-date' behavior. - Add early detection in get_state_authorization_for_specific_owner_repo - Return success for all-noop pushes without requiring purgatory event - Document behavior in inline-authorization.md
This commit is contained in:
@@ -352,6 +352,10 @@ pub async fn authorize_push(
|
||||
- If no event found, create placeholder (git-data-first scenario)
|
||||
- Collect PR events from purgatory for post-push processing
|
||||
|
||||
**No-Op Push Acceptance:** Pushes where all refs have `old_oid == new_oid` are accepted without requiring a purgatory state event, matching Git's "Everything up-to-date" behavior and avoiding race condition rejections.
|
||||
|
||||
---
|
||||
|
||||
## State Event Authorization
|
||||
|
||||
State events (kind 30618) undergo authorization checks at three points (defense-in-depth):
|
||||
|
||||
@@ -575,6 +575,28 @@ pub async fn get_state_authorization_for_specific_owner_repo(
|
||||
owner_pubkey
|
||||
);
|
||||
|
||||
// Accept pushes where all refs are already at the desired state (old_oid == new_oid)
|
||||
// This handles race conditions where state events are applied between fetch and push
|
||||
if !pushed_refs.is_empty() {
|
||||
let all_refs_unchanged = pushed_refs
|
||||
.iter()
|
||||
.all(|(old_oid, new_oid, _)| old_oid == new_oid);
|
||||
|
||||
if all_refs_unchanged {
|
||||
debug!(
|
||||
"All pushed refs unchanged (old_oid == new_oid) for {} owned by {}, accepting without purgatory check",
|
||||
identifier, owner_pubkey
|
||||
);
|
||||
return Ok(AuthorizationResult {
|
||||
authorized: true,
|
||||
reason: "Push accepted: all refs already at desired state (no-op)".to_string(),
|
||||
state: None,
|
||||
maintainers: authorized.into_iter().collect(),
|
||||
purgatory_events: vec![],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Check purgatory for matching state events
|
||||
// Convert pushed refs to RefUpdate (filter out refs/nostr/* refs)
|
||||
let pushed_updates: Vec<RefUpdate> = pushed_refs
|
||||
|
||||
Reference in New Issue
Block a user