From 95b7a60979e6c2ed75c823a945d6df6e92da0873 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Tue, 15 Oct 2024 21:30:09 +0800 Subject: [PATCH] rewrite: extract `compute_internal_parents_within` function --- lib/src/rewrite.rs | 52 +++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/lib/src/rewrite.rs b/lib/src/rewrite.rs index c02a4cdce..83a638b2f 100644 --- a/lib/src/rewrite.rs +++ b/lib/src/rewrite.rs @@ -511,27 +511,9 @@ pub fn move_commits( .map_err(|err| err.expect_backend_error())?; // Compute the parents of all commits in the connected target set, allowing only - // commits in the target set as parents. The parents of each commit are - // identical to the ones found using a preorder DFS of the node's ancestors, - // starting from the node itself, and avoiding traversing an edge if the - // parent is in the target set. - let mut connected_target_commits_internal_parents: HashMap> = - HashMap::new(); - for commit in connected_target_commits.iter().rev() { - // The roots of the set will not have any parents found in - // `connected_target_commits_internal_parents`, and will be stored as an empty - // vector. - let mut new_parents = vec![]; - for old_parent in commit.parent_ids() { - if target_commit_ids.contains(old_parent) { - new_parents.push(old_parent.clone()); - } else if let Some(parents) = connected_target_commits_internal_parents.get(old_parent) - { - new_parents.extend(parents.iter().cloned()); - } - } - connected_target_commits_internal_parents.insert(commit.id().clone(), new_parents); - } + // commits in the target set as parents. + let connected_target_commits_internal_parents = + compute_internal_parents_within(&target_commit_ids, &connected_target_commits); // Compute the roots of `target_commits` if not provided. let target_roots: HashSet<_> = if let Some(target_roots) = target_roots { @@ -846,6 +828,34 @@ pub fn move_commits( }) } +/// Computes the internal parents of all commits in a connected commit graph, +/// allowing only commits in the target set as parents. +/// +/// The parents of each commit are identical to the ones found using a preorder +/// DFS of the node's ancestors, starting from the node itself, and avoiding +/// traversing an edge if the parent is in the target set. `graph_commits` +/// should be in reverse topological order. +fn compute_internal_parents_within( + target_commit_ids: &HashSet, + graph_commits: &[Commit], +) -> HashMap> { + let mut internal_parents: HashMap> = HashMap::new(); + for commit in graph_commits.iter().rev() { + // The roots of the set will not have any parents found in `internal_parents`, + // and will be stored as an empty vector. + let mut new_parents = vec![]; + for old_parent in commit.parent_ids() { + if target_commit_ids.contains(old_parent) { + new_parents.push(old_parent.clone()); + } else if let Some(parents) = internal_parents.get(old_parent) { + new_parents.extend(parents.iter().cloned()); + } + } + internal_parents.insert(commit.id().clone(), new_parents); + } + internal_parents +} + pub struct CommitToSquash { pub commit: Commit, pub selected_tree: MergedTree,