diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/nostr/policy/state.rs | 107 |
1 files changed, 106 insertions, 1 deletions
diff --git a/src/nostr/policy/state.rs b/src/nostr/policy/state.rs index 1203890..48435ea 100644 --- a/src/nostr/policy/state.rs +++ b/src/nostr/policy/state.rs | |||
| @@ -125,7 +125,27 @@ impl StatePolicy { | |||
| 125 | { | 125 | { |
| 126 | let repo_path = | 126 | let repo_path = |
| 127 | self.ctx.git_data_path.join(annoucement.repo_path().clone()); | 127 | self.ctx.git_data_path.join(annoucement.repo_path().clone()); |
| 128 | // TODO - if repo_path != repo_with_git_data, pass as a datasource for missing data? | 128 | |
| 129 | if !repo_path.exists() { | ||
| 130 | // eg if annoucement doesnt list repo (but stored as its in maintainer set) | ||
| 131 | continue; | ||
| 132 | } | ||
| 133 | // If repo_path != repo_with_git_data, copy missing oids first | ||
| 134 | if repo_path != repo_with_git_data { | ||
| 135 | if let Err(e) = self.copy_missing_oids( | ||
| 136 | &repo_with_git_data, | ||
| 137 | &repo_path, | ||
| 138 | &state, | ||
| 139 | ) { | ||
| 140 | tracing::warn!( | ||
| 141 | "Failed to copy oids from {} to {}: {}", | ||
| 142 | repo_with_git_data.display(), | ||
| 143 | repo_path.display(), | ||
| 144 | e | ||
| 145 | ); | ||
| 146 | } | ||
| 147 | } | ||
| 148 | |||
| 129 | let result = self.align_repository_with_state(&repo_path, &state); | 149 | let result = self.align_repository_with_state(&repo_path, &state); |
| 130 | repo_count += 1; | 150 | repo_count += 1; |
| 131 | tracing::info!( | 151 | tracing::info!( |
| @@ -335,6 +355,91 @@ impl StatePolicy { | |||
| 335 | 355 | ||
| 336 | result | 356 | result |
| 337 | } | 357 | } |
| 358 | |||
| 359 | /// Copy missing OIDs from a source repository to a target repository | ||
| 360 | /// | ||
| 361 | /// Identifies commits referenced in the state that are missing from the target | ||
| 362 | /// repository and copies them from the source repository using git fetch. | ||
| 363 | /// | ||
| 364 | /// # Arguments | ||
| 365 | /// * `source_repo` - Path to repository containing the commits | ||
| 366 | /// * `target_repo` - Path to repository to receive the commits | ||
| 367 | /// * `state` - Repository state containing commit references | ||
| 368 | /// | ||
| 369 | /// # Returns | ||
| 370 | /// Ok(()) on success, Err with error message on failure | ||
| 371 | fn copy_missing_oids( | ||
| 372 | &self, | ||
| 373 | source_repo: &Path, | ||
| 374 | target_repo: &Path, | ||
| 375 | state: &RepositoryState, | ||
| 376 | ) -> Result<(), String> { | ||
| 377 | use std::process::Command; | ||
| 378 | |||
| 379 | // Collect all commits referenced in the state | ||
| 380 | let mut commits_to_check = Vec::new(); | ||
| 381 | |||
| 382 | for branch in &state.branches { | ||
| 383 | if !branch.commit.starts_with("ref: ") { | ||
| 384 | commits_to_check.push(&branch.commit); | ||
| 385 | } | ||
| 386 | } | ||
| 387 | |||
| 388 | for tag in &state.tags { | ||
| 389 | if !tag.commit.starts_with("ref: ") { | ||
| 390 | commits_to_check.push(&tag.commit); | ||
| 391 | } | ||
| 392 | } | ||
| 393 | |||
| 394 | // Identify missing commits | ||
| 395 | let mut missing_commits = Vec::new(); | ||
| 396 | for commit in commits_to_check { | ||
| 397 | if !git::oid_exists(target_repo, commit) { | ||
| 398 | missing_commits.push(commit); | ||
| 399 | } | ||
| 400 | } | ||
| 401 | |||
| 402 | if missing_commits.is_empty() { | ||
| 403 | tracing::debug!( | ||
| 404 | "No missing commits to copy from {} to {}", | ||
| 405 | source_repo.display(), | ||
| 406 | target_repo.display() | ||
| 407 | ); | ||
| 408 | return Ok(()); | ||
| 409 | } | ||
| 410 | |||
| 411 | tracing::info!( | ||
| 412 | "Copying {} missing commits from {} to {}", | ||
| 413 | missing_commits.len(), | ||
| 414 | source_repo.display(), | ||
| 415 | target_repo.display() | ||
| 416 | ); | ||
| 417 | |||
| 418 | // Fetch each missing commit from source to target | ||
| 419 | for commit in &missing_commits { | ||
| 420 | let output = Command::new("git") | ||
| 421 | .args([ | ||
| 422 | "fetch", | ||
| 423 | source_repo.to_str().ok_or("Invalid source path")?, | ||
| 424 | commit, | ||
| 425 | ]) | ||
| 426 | .current_dir(target_repo) | ||
| 427 | .output() | ||
| 428 | .map_err(|e| format!("Failed to execute git fetch: {}", e))?; | ||
| 429 | |||
| 430 | if !output.status.success() { | ||
| 431 | let stderr = String::from_utf8_lossy(&output.stderr); | ||
| 432 | return Err(format!( | ||
| 433 | "git fetch failed for commit {}: {}", | ||
| 434 | commit, stderr | ||
| 435 | )); | ||
| 436 | } | ||
| 437 | |||
| 438 | tracing::debug!("Copied commit {} to {}", commit, target_repo.display()); | ||
| 439 | } | ||
| 440 | |||
| 441 | Ok(()) | ||
| 442 | } | ||
| 338 | } | 443 | } |
| 339 | 444 | ||
| 340 | fn find_repo_with_git_data( | 445 | fn find_repo_with_git_data( |