aboutsummaryrefslogtreecommitdiffstats
path: root/repository_test.go
diff options
context:
space:
mode:
authorPaulo Gomes <paulo.gomes@suse.com>2024-03-09 09:00:21 +0000
committerPaulo Gomes <paulo.gomes@suse.com>2024-03-09 09:00:21 +0000
commit3ee5bc9dd308a5503d60cc26d17d7f10df28c37a (patch)
treecdc736274162b804e12d4bd55617b5811d470248 /repository_test.go
parent4bed23037f0e374d85bce1506e9df98ce0cfcd32 (diff)
downloadgo-git-3ee5bc9dd308a5503d60cc26d17d7f10df28c37a.tar.gz
git: Implement Merge function with initial FastForwardMerge support
Introduces the Merge function for merging branches in the codebase. Currently, the function only supports FastForwardMerge strategy, meaning it can efficiently update the target branch pointer if the source branch history is a linear descendant. Support for additional merge strategies (e.g., three-way merge) will be added in future commits. Signed-off-by: Paulo Gomes <paulo.gomes@suse.com>
Diffstat (limited to 'repository_test.go')
-rw-r--r--repository_test.go126
1 files changed, 90 insertions, 36 deletions
diff --git a/repository_test.go b/repository_test.go
index bcfecc7..b211f8c 100644
--- a/repository_test.go
+++ b/repository_test.go
@@ -82,7 +82,7 @@ func (s *RepositorySuite) TestInitWithInvalidDefaultBranch(c *C) {
c.Assert(err, NotNil)
}
-func createCommit(c *C, r *Repository) {
+func createCommit(c *C, r *Repository) plumbing.Hash {
// Create a commit so there is a HEAD to check
wt, err := r.Worktree()
c.Assert(err, IsNil)
@@ -101,13 +101,14 @@ func createCommit(c *C, r *Repository) {
Email: "go-git@fake.local",
When: time.Now(),
}
- _, err = wt.Commit("test commit message", &CommitOptions{
+
+ h, err := wt.Commit("test commit message", &CommitOptions{
All: true,
Author: &author,
Committer: &author,
})
c.Assert(err, IsNil)
-
+ return h
}
func (s *RepositorySuite) TestInitNonStandardDotGit(c *C) {
@@ -440,56 +441,109 @@ func (s *RepositorySuite) TestCreateBranchAndBranch(c *C) {
}
func (s *RepositorySuite) TestMergeFF(c *C) {
- r, _ := Init(memory.NewStorage(), memfs.New())
- err := r.clone(context.Background(), &CloneOptions{
- URL: s.GetBasicLocalRepositoryURL(),
+ r, err := Init(memory.NewStorage(), memfs.New())
+ c.Assert(err, IsNil)
+ c.Assert(r, NotNil)
+
+ createCommit(c, r)
+ createCommit(c, r)
+ createCommit(c, r)
+ lastCommit := createCommit(c, r)
+
+ wt, err := r.Worktree()
+ c.Assert(err, IsNil)
+
+ targetBranch := plumbing.NewBranchReferenceName("foo")
+ err = wt.Checkout(&CheckoutOptions{
+ Hash: lastCommit,
+ Create: true,
+ Branch: targetBranch,
})
c.Assert(err, IsNil)
+
+ createCommit(c, r)
+ fooHash := createCommit(c, r)
+
+ // Checkout the master branch so that we can try to merge foo into it.
+ err = wt.Checkout(&CheckoutOptions{
+ Branch: plumbing.Master,
+ })
+ c.Assert(err, IsNil)
+
head, err := r.Head()
c.Assert(err, IsNil)
+ c.Assert(head.Hash(), Equals, lastCommit)
+
+ targetRef := plumbing.NewHashReference(targetBranch, fooHash)
+ c.Assert(targetRef, NotNil)
- mergeBranchRefname := plumbing.NewBranchReferenceName("foo")
- err = r.Storer.SetReference(plumbing.NewHashReference(mergeBranchRefname, head.Hash()))
+ err = r.Merge(*targetRef, MergeOptions{
+ Strategy: FastForwardMerge,
+ })
c.Assert(err, IsNil)
- commit, err := r.CommitObject(head.Hash())
+ head, err = r.Head()
c.Assert(err, IsNil)
- treeHash := commit.TreeHash
+ c.Assert(head.Hash(), Equals, fooHash)
+}
- hash := commit.Hash
+func (s *RepositorySuite) TestMergeFF_Invalid(c *C) {
+ r, err := Init(memory.NewStorage(), memfs.New())
+ c.Assert(err, IsNil)
+ c.Assert(r, NotNil)
- for i := 0; i < 10; i++ {
- commit = &object.Commit{
- Author: object.Signature{
- Name: "A U Thor",
- Email: "author@example.com",
- },
- Committer: object.Signature{
- Name: "A U Thor",
- Email: "author@example.com",
- },
- Message: fmt.Sprintf("commit #%d", i),
- TreeHash: treeHash,
- ParentHashes: []plumbing.Hash{
- hash,
- },
- }
+ // Keep track of the first commit, which will be the
+ // reference to create the target branch so that we
+ // can simulate a non-ff merge.
+ firstCommit := createCommit(c, r)
+ createCommit(c, r)
+ createCommit(c, r)
+ lastCommit := createCommit(c, r)
- o := r.Storer.NewEncodedObject()
- c.Assert(commit.Encode(o), IsNil)
- hash, err = r.Storer.SetEncodedObject(o)
- }
+ wt, err := r.Worktree()
+ c.Assert(err, IsNil)
+
+ targetBranch := plumbing.NewBranchReferenceName("foo")
+ err = wt.Checkout(&CheckoutOptions{
+ Hash: firstCommit,
+ Create: true,
+ Branch: targetBranch,
+ })
- mergeBranchRef := plumbing.NewHashReference(mergeBranchRefname, hash)
- c.Assert(r.Storer.SetReference(mergeBranchRef), IsNil)
+ c.Assert(err, IsNil)
- err = r.Merge(*mergeBranchRef, MergeOptions{
- FFOnly: true,
+ createCommit(c, r)
+ h := createCommit(c, r)
+
+ // Checkout the master branch so that we can try to merge foo into it.
+ err = wt.Checkout(&CheckoutOptions{
+ Branch: plumbing.Master,
+ })
+ c.Assert(err, IsNil)
+
+ head, err := r.Head()
+ c.Assert(err, IsNil)
+ c.Assert(head.Hash(), Equals, lastCommit)
+
+ targetRef := plumbing.NewHashReference(targetBranch, h)
+ c.Assert(targetRef, NotNil)
+
+ err = r.Merge(*targetRef, MergeOptions{
+ Strategy: MergeStrategy(10),
})
+ c.Assert(err, Equals, ErrUnsupportedMergeStrategy)
+
+ // Failed merge operations must not change HEAD.
+ head, err = r.Head()
c.Assert(err, IsNil)
+ c.Assert(head.Hash(), Equals, lastCommit)
+
+ err = r.Merge(*targetRef, MergeOptions{})
+ c.Assert(err, Equals, ErrFastForwardMergeNotPossible)
head, err = r.Head()
- c.Assert(head.Hash(), Equals, mergeBranchRef.Hash())
+ c.Assert(err, IsNil)
+ c.Assert(head.Hash(), Equals, lastCommit)
}
func (s *RepositorySuite) TestCreateBranchUnmarshal(c *C) {