From 82aa2d17607b54a910b7a43efb034d0703aaf9f3 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 26 Aug 2024 16:08:06 +0200 Subject: [PATCH] use `gix` powered merge-base for performance and reduced memory consumption --- Cargo.lock | 3 +++ crates/gitbutler-branch-actions/Cargo.toml | 2 +- crates/gitbutler-branch-actions/src/branch.rs | 23 +++++++++++-------- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d443e47a1..13bef08da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3452,12 +3452,15 @@ name = "gix-revision" version = "0.29.0" source = "git+https://github.com/Byron/gitoxide?rev=649f5882cbebadf1133fa5f310e09b4aab77217e#649f5882cbebadf1133fa5f310e09b4aab77217e" dependencies = [ + "bitflags 2.6.0", "bstr", "gix-commitgraph 0.24.3 (git+https://github.com/Byron/gitoxide?rev=649f5882cbebadf1133fa5f310e09b4aab77217e)", "gix-date 0.9.0", "gix-hash 0.14.2 (git+https://github.com/Byron/gitoxide?rev=649f5882cbebadf1133fa5f310e09b4aab77217e)", + "gix-hashtable 0.5.2 (git+https://github.com/Byron/gitoxide?rev=649f5882cbebadf1133fa5f310e09b4aab77217e)", "gix-object 0.44.0", "gix-revwalk 0.15.0", + "gix-trace 0.1.9 (git+https://github.com/Byron/gitoxide?rev=649f5882cbebadf1133fa5f310e09b4aab77217e)", "thiserror", ] diff --git a/crates/gitbutler-branch-actions/Cargo.toml b/crates/gitbutler-branch-actions/Cargo.toml index be70d0b04..9e193e360 100644 --- a/crates/gitbutler-branch-actions/Cargo.toml +++ b/crates/gitbutler-branch-actions/Cargo.toml @@ -9,7 +9,7 @@ publish = false tracing.workspace = true anyhow = "1.0.86" git2.workspace = true -gix = { workspace = true, features = ["blob-diff"] } +gix = { workspace = true, features = ["blob-diff", "revision"] } tokio.workspace = true gitbutler-oplog.workspace = true gitbutler-repo.workspace = true diff --git a/crates/gitbutler-branch-actions/src/branch.rs b/crates/gitbutler-branch-actions/src/branch.rs index 21216fccb..f73993617 100644 --- a/crates/gitbutler-branch-actions/src/branch.rs +++ b/crates/gitbutler-branch-actions/src/branch.rs @@ -512,14 +512,20 @@ pub fn get_branch_listing_details( let merge_bases = std::thread::Builder::new() .name("gitbutler-mergebases".into()) .spawn({ - let git_dir = ctx.repository().path().to_owned(); + let repo = repo.clone().into_sync(); move || -> anyhow::Result<()> { - let git2_repo = git2::Repository::open(git_dir)?; + let mut repo = repo.to_thread_local(); + repo.object_cache_size_if_unset(50 * 1024 * 1024); + let cache = repo.commit_graph_if_enabled()?; for (other_branch_commit_id, branch_head) in all_other_branch_commit_ids { - // TODO(ST): use `gix` for two-way mergebases. - let base = git2_repo - .merge_base(other_branch_commit_id, branch_head) - .ok(); + let base = repo + .merge_base_with_cache( + git2_to_gix_object_id(other_branch_commit_id), + git2_to_gix_object_id(branch_head), + cache.as_ref(), + ) + .ok() + .map(gix::Id::detach); if merge_tx.send(base).is_err() { break; } @@ -534,8 +540,7 @@ pub fn get_branch_listing_details( }; let branch_head = git2_to_gix_object_id(branch.head); - let gix_base = git2_to_gix_object_id(base); - let base_commit = repo.find_object(gix_base)?.try_into_commit()?; + let base_commit = repo.find_object(base)?.try_into_commit()?; let base_tree = base_commit.tree()?; let head_tree = repo.find_object(branch_head)?.peel_to_tree()?; @@ -558,7 +563,7 @@ pub fn get_branch_listing_details( let mut authors = HashSet::new(); let revwalk = repo .rev_walk(Some(branch_head)) - .with_pruned(Some(gix_base)) + .with_pruned(Some(base)) .all()?; for commit_info in revwalk { let commit_info = commit_info?;