upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/lib/repo_state.rs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2026-02-27 15:40:24 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2026-02-27 15:46:37 +0000
commit28ad5440c7184de9833f8448bc90153ee4499c83 (patch)
tree92e72a62cc0465b11c4ec2028f9f6d8c4058057e /src/lib/repo_state.rs
parent3aa9b7a8e49d8ec5a87693d3f52ae2c77f036ff2 (diff)
fix: annotated tags missing from list due to dropped peeled refs
RepoState::try_from was explicitly discarding all refs/tags/*^{} entries ("peeled" refs) when parsing the nostr state event. This meant the list command only advertised the tag object OID, but git requires two lines for annotated tags: <tag-object-oid> refs/tags/v1.0.0 <commit-oid> refs/tags/v1.0.0^{} Without the ^{} peeled line git cannot resolve the tag to a commit, so git fetch --prune treats it as unresolvable and deletes it. The nostr state event already stores both entries correctly (written by generate_updated_state in push.rs). The fix simply stops try_from from discarding the ^{} entries on read, so they flow through to the list output unchanged.
Diffstat (limited to 'src/lib/repo_state.rs')
-rw-r--r--src/lib/repo_state.rs7
1 files changed, 5 insertions, 2 deletions
diff --git a/src/lib/repo_state.rs b/src/lib/repo_state.rs
index 345f05c..223fe56 100644
--- a/src/lib/repo_state.rs
+++ b/src/lib/repo_state.rs
@@ -22,11 +22,14 @@ impl RepoState {
22 let mut state = HashMap::new(); 22 let mut state = HashMap::new();
23 for tag in event.tags.iter() { 23 for tag in event.tags.iter() {
24 if let Some(name) = tag.as_slice().first() { 24 if let Some(name) = tag.as_slice().first() {
25 // include ^{} peeled refs for annotated tags: git requires
26 // both "<tag-oid> refs/tags/v1.0.0" and
27 // "<commit-oid> refs/tags/v1.0.0^{}" in the list output so
28 // it can resolve the tag to a commit. without the ^{} line
29 // git fetch --prune deletes the tag as unresolvable.
25 if ["refs/heads/", "refs/tags", "HEAD"] 30 if ["refs/heads/", "refs/tags", "HEAD"]
26 .iter() 31 .iter()
27 .any(|s| name.starts_with(*s)) 32 .any(|s| name.starts_with(*s))
28 // dont include dereferenced tags
29 && !name.ends_with("^{}")
30 { 33 {
31 if let Some(value) = tag.as_slice().get(1) { 34 if let Some(value) = tag.as_slice().get(1) {
32 if Oid::from_str(value).is_ok() || value.contains("ref: refs/") { 35 if Oid::from_str(value).is_ok() || value.contains("ref: refs/") {