diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-27 15:40:24 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-27 15:46:37 +0000 |
| commit | 28ad5440c7184de9833f8448bc90153ee4499c83 (patch) | |
| tree | 92e72a62cc0465b11c4ec2028f9f6d8c4058057e /src/lib | |
| parent | 3aa9b7a8e49d8ec5a87693d3f52ae2c77f036ff2 (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')
| -rw-r--r-- | src/lib/repo_state.rs | 7 |
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/") { |