Skip to content

Commit

Permalink
Finish the entire merge implementation and cover everything with tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Oct 21, 2024
1 parent e72b81e commit 8ceaada
Show file tree
Hide file tree
Showing 7 changed files with 838 additions and 153 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions gix-merge/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ document-features = { version = "0.2.0", optional = true }
[dev-dependencies]
gix-testtools = { path = "../tests/tools" }
gix-odb = { path = "../gix-odb" }
gix-utils = { version = "^0.1.12", path = "../gix-utils" }
pretty_assertions = "1.4.0"

[package.metadata.docs.rs]
Expand Down
25 changes: 17 additions & 8 deletions gix-merge/src/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ pub enum Error {
}

/// A way to configure [`commit()`](crate::commit()).
#[derive(Default, Debug, Copy, Clone)]
#[derive(Default, Debug, Clone)]
pub struct Options {
/// If `true`, merging unrelated commits is allowed, with the merge-base being assumed as empty tree.
pub allow_missing_merge_base: bool,
/// Options to define how trees should be merged.
pub tree_merge: crate::tree::Options,
/// Options to define how to merge blobs.
///
/// Note that these are temporarily overwritten if multiple merge-bases are merged into one.
pub blob_merge: crate::blob::platform::merge::Options,
/// If `true`, do not merge multiple merge-bases into one. Instead, just use the first one.
// TODO: test
#[doc(alias = "no_recursive", alias = "git2")]
pub use_first_merge_base: bool,
}

pub(super) mod function {
Expand All @@ -51,21 +51,29 @@ pub(super) mod function {
///
/// Note that `objects` *should* have an object cache to greatly accelerate tree-retrieval.
#[allow(clippy::too_many_arguments)]
pub fn commit<'objects>(
pub fn commit<'objects, E>(
our_commit: gix_hash::ObjectId,
their_commit: gix_hash::ObjectId,
mut labels: crate::blob::builtin_driver::text::Labels<'_>,
graph: &mut gix_revwalk::Graph<'_, '_, gix_revwalk::graph::Commit<gix_revision::merge_base::Flags>>,
diff_resource_cache: &mut gix_diff::blob::Platform,
blob_merge: &mut crate::blob::Platform,
objects: &'objects impl gix_object::FindObjectOrHeader,
write_blob_to_odb: impl FnMut(&[u8]) -> Result<gix_hash::ObjectId, E>,
options: Options,
) -> Result<crate::tree::Outcome<'objects>, Error> {
) -> Result<crate::tree::Outcome<'objects>, Error>
where
E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
{
let merge_bases_commit_ids = gix_revision::merge_base(our_commit, &[their_commit], graph)?;
let (merge_base_commit_id, ancestor_name) = match merge_bases_commit_ids {
Some(base_commit) if base_commit.len() == 1 => (base_commit[0], None),
Some(base_commits) => {
let virtual_base_tree = *base_commits.first().expect("TODO: merge multiple bases into one");
let virtual_base_tree = if options.use_first_merge_base {
*base_commits.first().expect("TODO: merge multiple bases into one")
} else {
todo!("merge multiple merge bases")
};
(virtual_base_tree, Some("merged common ancestors".into()))
}
None => {
Expand Down Expand Up @@ -97,6 +105,7 @@ pub(super) mod function {
&their_tree_id,
labels,
objects,
write_blob_to_odb,
&mut state,
diff_resource_cache,
blob_merge,
Expand Down
Loading

0 comments on commit 8ceaada

Please sign in to comment.