diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-26 15:23:04 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-26 15:26:22 +0000 |
| commit | 54f0542a27e4ccab459d87283e4668d865ddd2bb (patch) | |
| tree | ddbbe7f6a4dce369076c7431aab1852d3619d516 | |
| parent | 300ab2a476f719c51966db90c9976eb55421962a (diff) | |
fix: store tag object OID in tracking ref for annotated tags after push
update_remote_refs_pushed was calling peel_to_commit() for all refs,
discarding the tag object OID for annotated tags. This caused a mismatch
with generate_updated_state, which correctly stores the tag object OID in
the nostr state event. ngit sync would then push the commit OID to grasp
servers that expected the tag object OID, causing rejections.
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | src/bin/git_remote_nostr/push.rs | 26 |
2 files changed, 23 insertions, 5 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 4130ce2..31716ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md | |||
| @@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 16 | 16 | ||
| 17 | - `git-remote-nostr` list now advertises the newest state event whose OIDs are all confirmed present on a git server or locally, rather than unconditionally using the latest nostr state event; this prevents catastrophic fetch/clone failures when a state event was published before the corresponding git push completed | 17 | - `git-remote-nostr` list now advertises the newest state event whose OIDs are all confirmed present on a git server or locally, rather than unconditionally using the latest nostr state event; this prevents catastrophic fetch/clone failures when a state event was published before the corresponding git push completed |
| 18 | - Tag tracking refs written with wrong path (`refs/remotes/origin/refs/tags/v1.0.0` instead of `refs/remotes/origin/v1.0.0`) after a push via `git-remote-nostr`, causing `ngit sync` to fail with "src refspec does not match any existing object" when syncing tags | 18 | - Tag tracking refs written with wrong path (`refs/remotes/origin/refs/tags/v1.0.0` instead of `refs/remotes/origin/v1.0.0`) after a push via `git-remote-nostr`, causing `ngit sync` to fail with "src refspec does not match any existing object" when syncing tags |
| 19 | - Annotated tag tracking refs stored with the peeled commit OID instead of the tag object OID after a push via `git-remote-nostr`; this caused `ngit sync` to push the wrong object to grasp servers, which rejected it because the nostr state event referenced the tag object OID | ||
| 20 | - `ngit sync --verbose` detailed per-relay view not shown; `--verbose` flag was ignored due to a logic error in `send_events` | ||
| 19 | - `ngit sync` using wrong refspec source (`refs/remotes/origin/refs/heads/master` instead of `refs/remotes/origin/master`), causing sync to fail with "src refspec does not match any existing object" | 21 | - `ngit sync` using wrong refspec source (`refs/remotes/origin/refs/heads/master` instead of `refs/remotes/origin/master`), causing sync to fail with "src refspec does not match any existing object" |
| 20 | - State event publish failures silently swallowed during push; summary now shows `"Published to X/N relays (failed: relay1 relay2)"` instead of unconditional success message | 22 | - State event publish failures silently swallowed during push; summary now shows `"Published to X/N relays (failed: relay1 relay2)"` instead of unconditional success message |
| 21 | - Grasp servers whose internal relay did not receive the state event are now skipped during push, with a clear warning; push fails with an error message when no servers remain | 23 | - Grasp servers whose internal relay did not receive the state event are now skipped during push, with a clear warning; push fails with an error message when no servers remain |
diff --git a/src/bin/git_remote_nostr/push.rs b/src/bin/git_remote_nostr/push.rs index b0e7726..bd1188b 100644 --- a/src/bin/git_remote_nostr/push.rs +++ b/src/bin/git_remote_nostr/push.rs | |||
| @@ -1524,7 +1524,7 @@ fn update_remote_refs_pushed( | |||
| 1524 | refspec: &str, | 1524 | refspec: &str, |
| 1525 | nostr_remote_url: &str, | 1525 | nostr_remote_url: &str, |
| 1526 | ) -> Result<()> { | 1526 | ) -> Result<()> { |
| 1527 | let (from, _) = refspec_to_from_to(refspec)?; | 1527 | let (from, to) = refspec_to_from_to(refspec)?; |
| 1528 | 1528 | ||
| 1529 | let target_ref_name = refspec_remote_ref_name(git_repo, refspec, nostr_remote_url)?; | 1529 | let target_ref_name = refspec_remote_ref_name(git_repo, refspec, nostr_remote_url)?; |
| 1530 | 1530 | ||
| @@ -1533,14 +1533,30 @@ fn update_remote_refs_pushed( | |||
| 1533 | remote_ref.delete()?; | 1533 | remote_ref.delete()?; |
| 1534 | } | 1534 | } |
| 1535 | } else { | 1535 | } else { |
| 1536 | let commit = reference_to_commit(git_repo, from) | 1536 | // For annotated tags, store the tag object OID (not the peeled commit) |
| 1537 | .context(format!("failed to get commit of reference {from}"))?; | 1537 | // to match what generate_updated_state puts in the nostr state event. |
| 1538 | // For branches and lightweight tags, store the commit OID as before. | ||
| 1539 | let oid = if to.starts_with("refs/tags/") { | ||
| 1540 | if let Ok(tag_obj) = git_repo | ||
| 1541 | .find_reference(from) | ||
| 1542 | .context(format!("failed to find reference: {from}"))? | ||
| 1543 | .peel(git2::ObjectType::Tag) | ||
| 1544 | { | ||
| 1545 | tag_obj.id() | ||
| 1546 | } else { | ||
| 1547 | reference_to_commit(git_repo, from) | ||
| 1548 | .context(format!("failed to get commit of reference {from}"))? | ||
| 1549 | } | ||
| 1550 | } else { | ||
| 1551 | reference_to_commit(git_repo, from) | ||
| 1552 | .context(format!("failed to get commit of reference {from}"))? | ||
| 1553 | }; | ||
| 1538 | if let Ok(mut remote_ref) = git_repo.find_reference(&target_ref_name) { | 1554 | if let Ok(mut remote_ref) = git_repo.find_reference(&target_ref_name) { |
| 1539 | remote_ref.set_target(commit, "updated by nostr remote helper")?; | 1555 | remote_ref.set_target(oid, "updated by nostr remote helper")?; |
| 1540 | } else { | 1556 | } else { |
| 1541 | git_repo.reference( | 1557 | git_repo.reference( |
| 1542 | &target_ref_name, | 1558 | &target_ref_name, |
| 1543 | commit, | 1559 | oid, |
| 1544 | false, | 1560 | false, |
| 1545 | "created by nostr remote helper", | 1561 | "created by nostr remote helper", |
| 1546 | )?; | 1562 | )?; |