From e0b52cd03d49d5c38539028ff05c8bc326d6a6dd Mon Sep 17 00:00:00 2001 From: Essien Ita Essien <34972+essiene@users.noreply.github.com> Date: Sat, 2 Nov 2024 11:04:02 +0000 Subject: [PATCH] git sync: Get heads and build candidate commits. ## Summary * [X] Get branch pre-fetch heads * [X] Build candidates from prefetch heads * [X] Fetch from remotes * [X] Get branch post-fetch heads * [ ] Rebase ## Details * Candidate commits (parent_id, child_id) are: * branch commits * and their descendants * which are not found in untracked remote branches Issue: #1039 --- cli/src/commands/git/sync.rs | 49 ++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/cli/src/commands/git/sync.rs b/cli/src/commands/git/sync.rs index 73406f94cc..b98503444b 100644 --- a/cli/src/commands/git/sync.rs +++ b/cli/src/commands/git/sync.rs @@ -38,6 +38,7 @@ pub fn cmd_git_sync( let mut tx = workspace_command.start_transaction(); let guard = tracing::debug_span!("git.sync.pre-fetch").entered(); let prefetch_heads = get_branch_heads(tx.base_repo().as_ref(), &args.branch)?; + let candidates = CandidateCommit::get(tx.repo(), &prefetch_heads)?; drop(guard); let guard = tracing::debug_span!("git.sync.fetch").entered(); git_fetch_all(ui, &mut tx, args.all_remotes)?; @@ -87,6 +88,54 @@ fn get_branch_heads( Ok(commits) } +#[derive(Eq, Ord, PartialEq, PartialOrd)] +pub struct CandidateCommit { + parent: CommitId, + child: CommitId, +} + +impl fmt::Display for CandidateCommit { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let parent = short_commit_hash(&self.parent); + let child = short_commit_hash(&self.child); + write!(f, "=> {parent} --> {child}") + } +} + +impl CandidateCommit { + fn get(repo: &dyn Repo, start: &[CommitId]) -> Result, CommandError> { + let commits: Vec = RevsetExpression::commits(start.to_vec()) + .descendants() + .minus(&RevsetExpression::remote_bookmarks( + StringPattern::everything(), + StringPattern::everything(), + Some(RemoteRefState::New), + )) + .resolve_user_expression(repo, &FailingSymbolResolver)? + .evaluate(repo)? + .iter() + .commits(repo.store()) + .try_collect()?; + + Ok(commits + .iter() + .flat_map(|commit| { + commit + .parent_ids() + .iter() + .map(|parent_id| { + let candidate = CandidateCommit { + parent: parent_id.clone(), + child: commit.id().clone(), + }; + tracing::debug!("candidate: {candidate}"); + candidate + }) + .collect::>() + }) + .collect::>()) + } +} fn git_fetch_all( ui: &mut Ui,