Fetch changes from the copied repository back to the main repository. Returns a `FetchResult` with `has_changes: false` if the branch has no new commits.
(
&self,
repo_path: &Path,
branch_name: &str,
repo_root: &Path,
source_commit: &str,
source_branch: Option<&str>,
git_town_enabled: bool,
)
| 577 | /// Fetch changes from the copied repository back to the main repository. |
| 578 | /// Returns a `FetchResult` with `has_changes: false` if the branch has no new commits. |
| 579 | pub async fn fetch_changes( |
| 580 | &self, |
| 581 | repo_path: &Path, |
| 582 | branch_name: &str, |
| 583 | repo_root: &Path, |
| 584 | source_commit: &str, |
| 585 | source_branch: Option<&str>, |
| 586 | git_town_enabled: bool, |
| 587 | ) -> Result<FetchResult, String> { |
| 588 | // Check if there are any changes by comparing HEAD with source commit |
| 589 | let current_head = git_operations::get_current_commit(repo_path).await?; |
| 590 | if current_head == source_commit { |
| 591 | return Ok(FetchResult { |
| 592 | has_changes: false, |
| 593 | warnings: vec![], |
| 594 | }); |
| 595 | } |
| 596 | |
| 597 | let repo_path_str = repo_path |
| 598 | .to_str() |
| 599 | .ok_or_else(|| "Invalid repo path".to_string())?; |
| 600 | |
| 601 | // Use the provided repository root |
| 602 | let main_repo = repo_root.to_path_buf(); |
| 603 | |
| 604 | // Add the copied repository as a remote in the main repository |
| 605 | let now: DateTime<Local> = Local::now(); |
| 606 | let remote_name = format!("tsk-temp-{}", now.format("%Y-%m-%d-%H%M%S")); |
| 607 | |
| 608 | // Synchronize git operations on the main repository |
| 609 | let (has_commits, warnings) = self |
| 610 | .ctx |
| 611 | .git_sync_manager() |
| 612 | .with_repo_lock(&main_repo, || async { |
| 613 | let mut warnings: Vec<String> = Vec::new(); |
| 614 | |
| 615 | git_operations::add_remote(&main_repo, &remote_name, repo_path_str).await?; |
| 616 | |
| 617 | // Validate that the branch is accessible before attempting fetch |
| 618 | if let Err(e) = |
| 619 | git_operations::validate_branch_accessible(repo_path, branch_name).await |
| 620 | { |
| 621 | // Clean up remote before returning error |
| 622 | let _ = git_operations::remove_remote(&main_repo, &remote_name).await; |
| 623 | return Err(format!( |
| 624 | "Cannot fetch branch '{}': {}\n\ |
| 625 | The branch was created but points to an inaccessible commit.\n\ |
| 626 | This may indicate git object database inconsistency.", |
| 627 | branch_name, e |
| 628 | )); |
| 629 | } |
| 630 | |
| 631 | // Fetch the specific branch from the remote |
| 632 | match git_operations::fetch_branch(&main_repo, &remote_name, branch_name).await { |
| 633 | Ok(_) => { |
| 634 | // Remove the temporary remote |
| 635 | git_operations::remove_remote(&main_repo, &remote_name).await?; |
| 636 |