diff options
Diffstat (limited to 'src/bin/ngit/sub_commands')
| -rw-r--r-- | src/bin/ngit/sub_commands/sync.rs | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/src/bin/ngit/sub_commands/sync.rs b/src/bin/ngit/sub_commands/sync.rs index 4d7e799..146bcbc 100644 --- a/src/bin/ngit/sub_commands/sync.rs +++ b/src/bin/ngit/sub_commands/sync.rs | |||
| @@ -78,6 +78,64 @@ pub async fn launch(args: &SubCommandArgs) -> Result<()> { | |||
| 78 | 78 | ||
| 79 | let nostr_state = get_state_from_cache(Some(git_repo_path), &repo_ref).await?; | 79 | let nostr_state = get_state_from_cache(Some(git_repo_path), &repo_ref).await?; |
| 80 | 80 | ||
| 81 | // When --force is given, rebuild and republish the state event even if | ||
| 82 | // nothing has changed. This lets users repair repos whose state event is | ||
| 83 | // missing ^{} peeled refs for annotated tags (or any other corruption) | ||
| 84 | // without needing to push a new ref. A fresh event is signed (new | ||
| 85 | // created_at) and broadcast to all repo relays and the user's write relays. | ||
| 86 | if args.force { | ||
| 87 | let (signer, user_ref, _) = load_existing_login( | ||
| 88 | &Some(&git_repo), | ||
| 89 | &None, | ||
| 90 | &None, | ||
| 91 | &None, | ||
| 92 | Some(&client), | ||
| 93 | false, // not silent — we need the user to authenticate if required | ||
| 94 | false, // prompt_for_password | ||
| 95 | false, // fetch_profile_updates | ||
| 96 | ) | ||
| 97 | .await | ||
| 98 | .context("authentication required to republish state; run 'ngit account login' first")?; | ||
| 99 | client.set_signer(signer.clone()).await; | ||
| 100 | // Backfill any missing ^{} peeled refs before rebuilding — the existing | ||
| 101 | // state event may predate the fix that started storing them. | ||
| 102 | let mut state = nostr_state.state.clone(); | ||
| 103 | let tag_refs: Vec<(String, String)> = state | ||
| 104 | .iter() | ||
| 105 | .filter(|(k, _)| k.starts_with("refs/tags/") && !k.ends_with("^{}")) | ||
| 106 | .map(|(k, v)| (k.clone(), v.clone())) | ||
| 107 | .collect(); | ||
| 108 | for (ref_name, tag_oid) in tag_refs { | ||
| 109 | let peeled_key = format!("{ref_name}^{{}}"); | ||
| 110 | if state.contains_key(&peeled_key) { | ||
| 111 | continue; | ||
| 112 | } | ||
| 113 | if let Ok(oid) = git2::Oid::from_str(&tag_oid) { | ||
| 114 | if git_repo | ||
| 115 | .git_repo | ||
| 116 | .find_object(oid, Some(git2::ObjectType::Tag)) | ||
| 117 | .is_ok() | ||
| 118 | { | ||
| 119 | if let Ok(commit_oid) = git_repo.get_commit_or_tip_of_reference(&ref_name) { | ||
| 120 | state.insert(peeled_key, commit_oid.to_string()); | ||
| 121 | } | ||
| 122 | } | ||
| 123 | } | ||
| 124 | } | ||
| 125 | let new_state = RepoState::build(repo_ref.identifier.clone(), state, &signer).await?; | ||
| 126 | send_events( | ||
| 127 | &client, | ||
| 128 | Some(git_repo_path), | ||
| 129 | vec![new_state.event], | ||
| 130 | user_ref.relays.write(), | ||
| 131 | repo_ref.relays.clone(), | ||
| 132 | true, | ||
| 133 | false, | ||
| 134 | ) | ||
| 135 | .await?; | ||
| 136 | println!("state event republished"); | ||
| 137 | } | ||
| 138 | |||
| 81 | // Publish the current state event to any grasp server relays that are | 139 | // Publish the current state event to any grasp server relays that are |
| 82 | // missing it or have a stale version. Grasp servers reject git pushes | 140 | // missing it or have a stale version. Grasp servers reject git pushes |
| 83 | // unless the state event is already present on their relay, so we must | 141 | // unless the state event is already present on their relay, so we must |
| @@ -129,7 +187,7 @@ pub async fn launch(args: &SubCommandArgs) -> Result<()> { | |||
| 129 | ) | 187 | ) |
| 130 | .await | 188 | .await |
| 131 | { | 189 | { |
| 132 | client.set_signer(signer).await; | 190 | client.set_signer(signer.clone()).await; |
| 133 | } | 191 | } |
| 134 | // Send only to the specific grasp relays that are missing or have a | 192 | // Send only to the specific grasp relays that are missing or have a |
| 135 | // stale state event — no user write relays. | 193 | // stale state event — no user write relays. |