diff --git a/Cargo.lock b/Cargo.lock index 418265dab6..adf62f4489 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2459,6 +2459,7 @@ dependencies = [ "anyhow", "bstr", "but-core", + "but-debugging", "but-rebase", "but-settings", "but-workspace", @@ -3029,6 +3030,7 @@ name = "gitbutler-testsupport" version = "0.0.0" dependencies = [ "anyhow", + "but-debugging", "but-settings", "git2", "gitbutler-branch", diff --git a/Cargo.toml b/Cargo.toml index 2f2b1252ea..e217e9a723 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,6 +73,7 @@ but-rebase = { path = "crates/but-rebase" } but-core = { path = "crates/but-core" } but-workspace = { path = "crates/but-workspace" } but-hunk-dependency = { path = "crates/but-hunk-dependency" } +but-debugging = { path = "crates/but-debugging" } [profile.release] codegen-units = 1 # Compile crates one after another so the compiler can optimize better diff --git a/crates/gitbutler-branch-actions/Cargo.toml b/crates/gitbutler-branch-actions/Cargo.toml index 2bd1b370f9..426305cbc7 100644 --- a/crates/gitbutler-branch-actions/Cargo.toml +++ b/crates/gitbutler-branch-actions/Cargo.toml @@ -49,6 +49,7 @@ toml.workspace = true pretty_assertions = "1.4" gitbutler-testsupport.workspace = true gitbutler-workspace.workspace = true +but-debugging.workspace = true gix = { workspace = true, features = [] } glob = "0.3.2" tempfile.workspace = true diff --git a/crates/gitbutler-branch-actions/tests/extra/mod.rs b/crates/gitbutler-branch-actions/tests/extra/mod.rs index 68f43560f8..5f877c3f8d 100644 --- a/crates/gitbutler-branch-actions/tests/extra/mod.rs +++ b/crates/gitbutler-branch-actions/tests/extra/mod.rs @@ -19,10 +19,12 @@ use gitbutler_branch_actions::{ BranchManagerExt, Get, }; use gitbutler_commit::{commit_ext::CommitExt, commit_headers::CommitHeadersV2}; +use gitbutler_oxidize::OidExt; use gitbutler_reference::{Refname, RemoteRefname}; use gitbutler_repo::RepositoryExt; use gitbutler_stack::{BranchOwnershipClaims, Target, VirtualBranchesHandle}; use gitbutler_testsupport::{commit_all, virtual_branches::set_test_target, Case, Suite}; +use gix::refs::transaction::PreviousValue; use pretty_assertions::assert_eq; #[test] @@ -829,6 +831,12 @@ fn merge_vbranch_upstream_clean_rebase() -> Result<()> { sha: target_oid, push_remote_name: None, })?; + ctx.gix_repository()?.reference( + "refs/remotes/origin/master".to_string(), + target_oid.to_gix(), + PreviousValue::Any, + "", + )?; // add some uncommitted work let file_path2 = Path::new("test2.txt"); @@ -959,6 +967,12 @@ fn merge_vbranch_upstream_conflict() -> Result<()> { sha: target_oid, push_remote_name: None, })?; + ctx.gix_repository()?.reference( + "refs/remotes/origin/master".to_string(), + target_oid.to_gix(), + PreviousValue::Any, + "", + )?; let remote_branch: RemoteRefname = "refs/remotes/origin/g-branch-1".parse().unwrap(); let branch_manager = ctx.branch_manager(); @@ -1764,6 +1778,8 @@ fn commit_partial_by_hunk() -> Result<()> { let list_result = internal::list_virtual_branches(ctx, guard.write_permission())?; let branches = list_result.branches; let branch = &branches.iter().find(|b| b.id == stack1_id).unwrap(); + + but_debugging::git_log(ctx.repo().path(), but_debugging::LogOptions::default().all(true)); assert_eq!(branch.files.len(), 1); assert_eq!(branch.files[0].hunks.len(), 2); @@ -1843,6 +1859,8 @@ fn commit_partial_by_file() -> Result<()> { let list_result = internal::list_virtual_branches(ctx, guard.write_permission())?; let branches = list_result.branches; let branch1 = &branches.iter().find(|b| b.id == stack1_id).unwrap(); + + but_debugging::git_log(ctx.repo().path(), but_debugging::LogOptions::default().all(true)); // branch one test.txt has just the 1st and 3rd hunks applied let commit2 = &branch1.series[0].clone()?.patches[0].id; @@ -1850,7 +1868,7 @@ fn commit_partial_by_file() -> Result<()> { .repo() .find_commit(commit2.to_owned()) .expect("failed to get commit object"); - + let tree = commit1.tree().expect("failed to get tree"); let file_list = tree_to_file_list(ctx.repo(), &tree); assert_eq!(file_list, vec!["test.txt", "test2.txt"]); diff --git a/crates/gitbutler-stack/src/stack.rs b/crates/gitbutler-stack/src/stack.rs index 5fcd71b4b1..f9288d9227 100644 --- a/crates/gitbutler-stack/src/stack.rs +++ b/crates/gitbutler-stack/src/stack.rs @@ -310,10 +310,23 @@ impl Stack { /// - If a target is not set for the project /// - If the head commit of the stack is not found pub fn merge_base(&self, stack_context: &StackContext) -> Result { - let target = stack_context.target(); - let repository = stack_context.repository(); - let merge_base = repository.merge_base(self.head(&repository.to_gix()?)?, target.sha)?; - Ok(merge_base) + let gix_repo = stack_context.repository().to_gix()?; + let git2_repository = stack_context.repository(); + let target_sha = gix_repo + .find_reference(&stack_context.target().branch.to_string())? + .peel_to_commit()? + .id; + let mut revwalk = git2_repository.revwalk()?; + let head_oid = self.head(&gix_repo)?; + revwalk.hide(head_oid)?; + revwalk.push(target_sha.to_git2())?; + revwalk.simplify_first_parent()?; + if let Some(last) = revwalk.last() { + let commit = git2_repository.find_commit(last?)?; + Ok(commit.parent_id(0)?) + } else { + Ok(head_oid) + } } /// An initialized stack has at least one head (branch). diff --git a/crates/gitbutler-testsupport/Cargo.toml b/crates/gitbutler-testsupport/Cargo.toml index b2b2590662..82e9d3a65c 100644 --- a/crates/gitbutler-testsupport/Cargo.toml +++ b/crates/gitbutler-testsupport/Cargo.toml @@ -32,5 +32,6 @@ gitbutler-stack.workspace = true but-settings.workspace = true gitbutler-oxidize.workspace = true gitbutler-commit.workspace = true +but-debugging.workspace = true termtree = "0.5.1" uuid.workspace = true diff --git a/crates/gitbutler-testsupport/src/lib.rs b/crates/gitbutler-testsupport/src/lib.rs index 1f709df88e..6725c66328 100644 --- a/crates/gitbutler-testsupport/src/lib.rs +++ b/crates/gitbutler-testsupport/src/lib.rs @@ -27,7 +27,9 @@ pub mod paths { pub mod virtual_branches { use gitbutler_command_context::CommandContext; + use gitbutler_oxidize::OidExt; use gitbutler_stack::{Target, VirtualBranchesHandle}; + use gix::refs::transaction::PreviousValue; use crate::empty_bare_repository; @@ -49,6 +51,13 @@ pub mod virtual_branches { }) .expect("failed to write target"); + ctx.gix_repository()?.reference( + "refs/remotes/origin/master".to_string(), + remote_repo.head().unwrap().target().unwrap().to_gix(), + PreviousValue::Any, + "", + )?; + gitbutler_branch_actions::update_workspace_commit(&vb_state, ctx) .expect("failed to update workspace");