ref:c1a037fb0edb4ac75ac06099ac046e31bf32ab3b

Add three-way merge and merge_base tests (Phase 7)

Implement tree-level three-way merge with recursive subtree support. Add merge_base/3 tests for the existing Walk module function. - New ExGitObjectstore.Merge module with merge_trees/4 and merge_commits/4 - Public API delegates: merge_commits/4, merge_trees/4 - 23 merge tests covering all three-way merge cases - 6 merge_base tests for Walk.merge_base/3 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SHA: c1a037fb0edb4ac75ac06099ac046e31bf32ab3b
Author: Cole Christensen <cole.christensen@macmillan.com>
Date: 2026-02-10 13:22
Parents: 726fbbc
4 files changed +876 -1
Type
lib/ex_git_objectstore.ex +23 −1
@@ -6,7 +6,7 @@
All git data (objects, refs, packs) is stored via a pluggable storage backend.
"""
alias ExGitObjectstore.{Object, ObjectResolver, Repo, Ref, Walk}
alias ExGitObjectstore.{Merge, Object, ObjectResolver, Repo, Ref, Walk}
alias ExGitObjectstore.Object.{Blob, Commit, Tree}
@type sha :: String.t()
@@ -181,6 +181,28 @@
{:ok, content} -> {:ok, byte_size(content)}
{:error, _} = err -> err
end
end
@doc """
Three-way merge of two commits.
Finds the merge base (LCA), then merges the trees.
Returns `{:ok, merged_tree_sha}` on clean merge, or
`{:error, {:conflicts, [conflict]}}` if there are conflicts.
"""
@spec merge_commits(Repo.t(), sha(), sha(), keyword()) ::
{:ok, sha()} | {:error, term()}
def merge_commits(%Repo{} = repo, ours_sha, theirs_sha, opts \\ []) do
Merge.merge_commits(repo, ours_sha, theirs_sha, opts)
end
@doc """
Three-way merge of tree objects given base, ours, and theirs tree SHAs.
"""
@spec merge_trees(Repo.t(), sha(), sha(), sha()) ::
{:ok, sha()} | {:error, term()}
def merge_trees(%Repo{} = repo, base_tree_sha, ours_tree_sha, theirs_tree_sha) do
Merge.merge_trees(repo, base_tree_sha, ours_tree_sha, theirs_tree_sha)
end
# Walk into nested tree directories by path components