Skip to content

Commit

Permalink
Merge pull request #4973 from gitbutlerapp/Testing-rebase
Browse files Browse the repository at this point in the history
Add tests for resolving indexes
  • Loading branch information
Caleb-T-Owens authored Sep 25, 2024
2 parents 598d60f + 9cbebba commit 50086f0
Show file tree
Hide file tree
Showing 9 changed files with 325 additions and 136 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ resolver = "2"
[workspace.dependencies]
bstr = "1.10.0"
# Add the `tracing` or `tracing-detail` features to see more of gitoxide in the logs. Useful to see which programs it invokes.
gix = { git = "https://github.com/Byron/gitoxide", rev = "72daa46bad9d397ef2cc48a3cffda23f414ccd8a", default-features = false, features = [] }
git2 = { version = "0.18.3", features = [
gix = { git = "https://github.com/Byron/gitoxide", rev = "72daa46bad9d397ef2cc48a3cffda23f414ccd8a", default-features = false, features = [
] }
git2 = { version = "0.19.0", features = [
"vendored-openssl",
"vendored-libgit2",
] }
Expand Down Expand Up @@ -95,4 +96,4 @@ debug = true # Enable debug symbols, for profiling
[profile.bench]
codegen-units = 256
lto = false
opt-level = 3
opt-level = 3
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ impl BranchManager<'_> {
// if not, we need to merge or rebase the branch to get it up to date

let merge_base = repo
.merge_base(default_target.sha, dbg!(branch.head))
.merge_base(default_target.sha, branch.head)
.context(format!(
"failed to find merge base between {} and {}",
default_target.sha, branch.head
Expand Down
1 change: 1 addition & 0 deletions crates/gitbutler-branch-actions/src/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use gitbutler_project::access::WorktreeWritePermission;
use tracing::instrument;

/// Represents the uncommitted status of the applied virtual branches in the workspace.
#[derive(Debug)]
pub struct VirtualBranchesStatus {
/// A collection of branches and their associated uncommitted file changes.
pub branches: Vec<(Branch, Vec<VirtualBranchFile>)>,
Expand Down
174 changes: 58 additions & 116 deletions crates/gitbutler-branch-actions/src/upstream_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,44 +478,12 @@ fn compute_resolutions(

#[cfg(test)]
mod test {
use std::fs;

use gitbutler_branch::BranchOwnershipClaims;
use tempfile::tempdir;
use gitbutler_testsupport::testing_repository::TestingRepository;
use uuid::Uuid;

use super::*;

fn commit_file<'a>(
repository: &'a git2::Repository,
parent: Option<&git2::Commit>,
files: &[(&str, &str)],
) -> git2::Commit<'a> {
for (file_name, contents) in files {
fs::write(repository.path().join("..").join(file_name), contents).unwrap();
}
let mut index = repository.index().unwrap();
// Make sure we're not having weird cached state
index.read(true).unwrap();
index
.add_all(["*"], git2::IndexAddOption::DEFAULT, None)
.unwrap();

let signature = git2::Signature::now("Caleb", "caleb@gitbutler.com").unwrap();
let commit = repository
.commit(
None,
&signature,
&signature,
"Committee",
&repository.find_tree(index.write_tree().unwrap()).unwrap(),
parent.map(|c| vec![c]).unwrap_or_default().as_slice(),
)
.unwrap();

repository.find_commit(commit).unwrap()
}

fn make_branch(head: git2::Oid, tree: git2::Oid) -> Branch {
Branch {
id: Uuid::new_v4().into(),
Expand All @@ -540,16 +508,15 @@ mod test {

#[test]
fn test_up_to_date_if_head_commits_equivalent() {
let tempdir = tempdir().unwrap();
let repository = git2::Repository::init(tempdir.path()).unwrap();
let initial_commit = commit_file(&repository, None, &[("foo.txt", "bar")]);
let head_commit = commit_file(&repository, Some(&initial_commit), &[("foo.txt", "baz")]);
let test_repository = TestingRepository::open();
let initial_commit = test_repository.commit_tree(None, &[("foo.txt", "bar")]);
let head_commit = test_repository.commit_tree(Some(&initial_commit), &[("foo.txt", "baz")]);

let context = UpstreamIntegrationContext {
_permission: None,
old_target: head_commit.clone(),
new_target: head_commit,
repository: &repository,
repository: &test_repository.repository,
virtual_branches_in_workspace: vec![],
target_branch_name: "main".to_string(),
};
Expand All @@ -562,17 +529,16 @@ mod test {

#[test]
fn test_updates_required_if_new_head_ahead() {
let tempdir = tempdir().unwrap();
let repository = git2::Repository::init(tempdir.path()).unwrap();
let initial_commit = commit_file(&repository, None, &[("foo.txt", "bar")]);
let old_target = commit_file(&repository, Some(&initial_commit), &[("foo.txt", "baz")]);
let new_target = commit_file(&repository, Some(&old_target), &[("foo.txt", "qux")]);
let test_repository = TestingRepository::open();
let initial_commit = test_repository.commit_tree(None, &[("foo.txt", "bar")]);
let old_target = test_repository.commit_tree(Some(&initial_commit), &[("foo.txt", "baz")]);
let new_target = test_repository.commit_tree(Some(&old_target), &[("foo.txt", "qux")]);

let context = UpstreamIntegrationContext {
_permission: None,
old_target,
new_target,
repository: &repository,
repository: &test_repository.repository,
virtual_branches_in_workspace: vec![],
target_branch_name: "main".to_string(),
};
Expand All @@ -585,19 +551,18 @@ mod test {

#[test]
fn test_empty_branch() {
let tempdir = tempdir().unwrap();
let repository = git2::Repository::init(tempdir.path()).unwrap();
let initial_commit = commit_file(&repository, None, &[("foo.txt", "bar")]);
let old_target = commit_file(&repository, Some(&initial_commit), &[("foo.txt", "baz")]);
let new_target = commit_file(&repository, Some(&old_target), &[("foo.txt", "qux")]);
let test_repository = TestingRepository::open();
let initial_commit = test_repository.commit_tree(None, &[("foo.txt", "bar")]);
let old_target = test_repository.commit_tree(Some(&initial_commit), &[("foo.txt", "baz")]);
let new_target = test_repository.commit_tree(Some(&old_target), &[("foo.txt", "qux")]);

let branch = make_branch(old_target.id(), old_target.tree_id());

let context = UpstreamIntegrationContext {
_permission: None,
old_target,
new_target,
repository: &repository,
repository: &test_repository.repository,
virtual_branches_in_workspace: vec![branch.clone()],
target_branch_name: "main".to_string(),
};
Expand All @@ -610,24 +575,19 @@ mod test {

#[test]
fn test_conflicted_head_branch() {
let tempdir = tempdir().unwrap();
let repository =
git2::Repository::init_opts(tempdir.path(), &gitbutler_testsupport::init_opts())
.unwrap();
let initial_commit = commit_file(&repository, None, &[("foo.txt", "bar")]);
// Create refs/heads/master
repository.branch("master", &initial_commit, false).unwrap();
let old_target = commit_file(&repository, Some(&initial_commit), &[("foo.txt", "baz")]);
let branch_head = commit_file(&repository, Some(&old_target), &[("foo.txt", "fux")]);
let new_target = commit_file(&repository, Some(&old_target), &[("foo.txt", "qux")]);
let test_repository = TestingRepository::open();
let initial_commit = test_repository.commit_tree(None, &[("foo.txt", "bar")]);
let old_target = test_repository.commit_tree(Some(&initial_commit), &[("foo.txt", "baz")]);
let branch_head = test_repository.commit_tree(Some(&old_target), &[("foo.txt", "fux")]);
let new_target = test_repository.commit_tree(Some(&old_target), &[("foo.txt", "qux")]);

let branch = make_branch(branch_head.id(), branch_head.tree_id());

let context = UpstreamIntegrationContext {
_permission: None,
old_target,
new_target: new_target.clone(),
repository: &repository,
repository: &test_repository.repository,
virtual_branches_in_workspace: vec![branch.clone()],
target_branch_name: "main".to_string(),
};
Expand Down Expand Up @@ -657,32 +617,32 @@ mod test {
panic!("Should be variant UpdatedObjects")
};

let head_commit = repository.find_commit(head).unwrap();
let head_commit = test_repository.repository.find_commit(head).unwrap();
assert_eq!(head_commit.parent(0).unwrap().id(), new_target.id());
assert!(head_commit.is_conflicted());

let head_tree = repository
let head_tree = test_repository
.repository
.find_real_tree(&head_commit, Default::default())
.unwrap();
assert_eq!(head_tree.id(), tree)
}

#[test]
fn test_conflicted_tree_branch() {
let tempdir = tempdir().unwrap();
let repository = git2::Repository::init(tempdir.path()).unwrap();
let initial_commit = commit_file(&repository, None, &[("foo.txt", "bar")]);
let old_target = commit_file(&repository, Some(&initial_commit), &[("foo.txt", "baz")]);
let branch_head = commit_file(&repository, Some(&old_target), &[("foo.txt", "fux")]);
let new_target = commit_file(&repository, Some(&old_target), &[("foo.txt", "qux")]);
let test_repository = TestingRepository::open();
let initial_commit = test_repository.commit_tree(None, &[("foo.txt", "bar")]);
let old_target = test_repository.commit_tree(Some(&initial_commit), &[("foo.txt", "baz")]);
let branch_head = test_repository.commit_tree(Some(&old_target), &[("foo.txt", "fux")]);
let new_target = test_repository.commit_tree(Some(&old_target), &[("foo.txt", "qux")]);

let branch = make_branch(old_target.id(), branch_head.tree_id());

let context = UpstreamIntegrationContext {
_permission: None,
old_target,
new_target,
repository: &repository,
repository: &test_repository.repository,
virtual_branches_in_workspace: vec![branch.clone()],
target_branch_name: "main".to_string(),
};
Expand All @@ -700,21 +660,20 @@ mod test {

#[test]
fn test_conflicted_head_and_tree_branch() {
let tempdir = tempdir().unwrap();
let repository = git2::Repository::init(tempdir.path()).unwrap();
let initial_commit = commit_file(&repository, None, &[("foo.txt", "bar")]);
let old_target = commit_file(&repository, Some(&initial_commit), &[("foo.txt", "baz")]);
let branch_head = commit_file(&repository, Some(&old_target), &[("foo.txt", "fux")]);
let branch_tree = commit_file(&repository, Some(&old_target), &[("foo.txt", "bax")]);
let new_target = commit_file(&repository, Some(&old_target), &[("foo.txt", "qux")]);
let test_repository = TestingRepository::open();
let initial_commit = test_repository.commit_tree(None, &[("foo.txt", "bar")]);
let old_target = test_repository.commit_tree(Some(&initial_commit), &[("foo.txt", "baz")]);
let branch_head = test_repository.commit_tree(Some(&old_target), &[("foo.txt", "fux")]);
let branch_tree = test_repository.commit_tree(Some(&old_target), &[("foo.txt", "bax")]);
let new_target = test_repository.commit_tree(Some(&old_target), &[("foo.txt", "qux")]);

let branch = make_branch(branch_head.id(), branch_tree.tree_id());

let context = UpstreamIntegrationContext {
_permission: None,
old_target,
new_target,
repository: &repository,
repository: &test_repository.repository,
virtual_branches_in_workspace: vec![branch.clone()],
target_branch_name: "main".to_string(),
};
Expand All @@ -732,19 +691,18 @@ mod test {

#[test]
fn test_integrated() {
let tempdir = tempdir().unwrap();
let repository = git2::Repository::init(tempdir.path()).unwrap();
let initial_commit = commit_file(&repository, None, &[("foo.txt", "bar")]);
let old_target = commit_file(&repository, Some(&initial_commit), &[("foo.txt", "baz")]);
let new_target = commit_file(&repository, Some(&old_target), &[("foo.txt", "qux")]);
let test_repository = TestingRepository::open();
let initial_commit = test_repository.commit_tree(None, &[("foo.txt", "bar")]);
let old_target = test_repository.commit_tree(Some(&initial_commit), &[("foo.txt", "baz")]);
let new_target = test_repository.commit_tree(Some(&old_target), &[("foo.txt", "qux")]);

let branch = make_branch(new_target.id(), new_target.tree_id());

let context = UpstreamIntegrationContext {
_permission: None,
old_target,
new_target,
repository: &repository,
repository: &test_repository.repository,
virtual_branches_in_workspace: vec![branch.clone()],
target_branch_name: "main".to_string(),
};
Expand All @@ -757,33 +715,25 @@ mod test {

#[test]
fn test_integrated_commit_with_uncommited_changes() {
let tempdir = tempdir().unwrap();
let repository = git2::Repository::init(tempdir.path()).unwrap();
let test_repository = TestingRepository::open();
let initial_commit =
commit_file(&repository, None, &[("foo.txt", "bar"), ("bar.txt", "bar")]);
let old_target = commit_file(
&repository,
test_repository.commit_tree(None, &[("foo.txt", "bar"), ("bar.txt", "bar")]);
let old_target = test_repository.commit_tree(
Some(&initial_commit),
&[("foo.txt", "baz"), ("bar.txt", "bar")],
);
let new_target = commit_file(
&repository,
Some(&old_target),
&[("foo.txt", "qux"), ("bar.txt", "bar")],
);
let tree = commit_file(
&repository,
Some(&old_target),
&[("foo.txt", "baz"), ("bar.txt", "qux")],
);
let new_target = test_repository
.commit_tree(Some(&old_target), &[("foo.txt", "qux"), ("bar.txt", "bar")]);
let tree = test_repository
.commit_tree(Some(&old_target), &[("foo.txt", "baz"), ("bar.txt", "qux")]);

let branch = make_branch(new_target.id(), tree.tree_id());

let context = UpstreamIntegrationContext {
_permission: None,
old_target,
new_target,
repository: &repository,
repository: &test_repository.repository,
virtual_branches_in_workspace: vec![branch.clone()],
target_branch_name: "main".to_string(),
};
Expand All @@ -796,31 +746,23 @@ mod test {

#[test]
fn test_safly_updatable() {
let tempdir = tempdir().unwrap();
let repository = git2::Repository::init(tempdir.path()).unwrap();
let initial_commit = commit_file(
&repository,
None,
&[("files-one.txt", "foo"), ("file-two.txt", "foo")],
);
let old_target = commit_file(
&repository,
let test_repository = TestingRepository::open();
let initial_commit =
test_repository.commit_tree(None, &[("files-one.txt", "foo"), ("file-two.txt", "foo")]);
let old_target = test_repository.commit_tree(
Some(&initial_commit),
&[("file-one.txt", "bar"), ("file-two.txt", "foo")],
);
let new_target = commit_file(
&repository,
let new_target = test_repository.commit_tree(
Some(&old_target),
&[("file-one.txt", "baz"), ("file-two.txt", "foo")],
);

let branch_head = commit_file(
&repository,
let branch_head = test_repository.commit_tree(
Some(&old_target),
&[("file-one.txt", "bar"), ("file-two.txt", "bar")],
);
let branch_tree = commit_file(
&repository,
let branch_tree = test_repository.commit_tree(
Some(&branch_head),
&[("file-one.txt", "bar"), ("file-two.txt", "baz")],
);
Expand All @@ -831,7 +773,7 @@ mod test {
_permission: None,
old_target,
new_target,
repository: &repository,
repository: &test_repository.repository,
virtual_branches_in_workspace: vec![branch.clone()],
target_branch_name: "main".to_string(),
};
Expand Down
Loading

0 comments on commit 50086f0

Please sign in to comment.