aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bug/bug.go2
-rw-r--r--identity/identity.go2
-rw-r--r--misc/random_bugs/create_random_bugs.go3
-rw-r--r--repository/git.go4
-rw-r--r--repository/mock_repo.go48
-rw-r--r--repository/repo.go18
-rw-r--r--repository/repo_testing.go130
7 files changed, 180 insertions, 27 deletions
diff --git a/bug/bug.go b/bug/bug.go
index 66609e6c..40537b0d 100644
--- a/bug/bug.go
+++ b/bug/bug.go
@@ -138,7 +138,7 @@ func readBug(repo repository.ClockedRepo, ref string) (*Bug, error) {
// Load each OperationPack
for _, hash := range hashes {
- entries, err := repo.ListEntries(hash)
+ entries, err := repo.ReadTree(hash)
if err != nil {
return nil, errors.Wrap(err, "can't list git tree entries")
}
diff --git a/identity/identity.go b/identity/identity.go
index c1bca4d6..d6504c52 100644
--- a/identity/identity.go
+++ b/identity/identity.go
@@ -118,7 +118,7 @@ func read(repo repository.Repo, ref string) (*Identity, error) {
}
for _, hash := range hashes {
- entries, err := repo.ListEntries(hash)
+ entries, err := repo.ReadTree(hash)
if err != nil {
return nil, errors.Wrap(err, "can't list git tree entries")
}
diff --git a/misc/random_bugs/create_random_bugs.go b/misc/random_bugs/create_random_bugs.go
index b5c19e63..7ac18db4 100644
--- a/misc/random_bugs/create_random_bugs.go
+++ b/misc/random_bugs/create_random_bugs.go
@@ -5,10 +5,11 @@ import (
"strings"
"time"
+ "github.com/icrowley/fake"
+
"github.com/MichaelMure/git-bug/bug"
"github.com/MichaelMure/git-bug/identity"
"github.com/MichaelMure/git-bug/repository"
- "github.com/icrowley/fake"
)
type opsGenerator func(bug.Interface, identity.Interface, int64)
diff --git a/repository/git.go b/repository/git.go
index e4cb57e6..83037307 100644
--- a/repository/git.go
+++ b/repository/git.go
@@ -337,8 +337,8 @@ func (repo *GitRepo) ListCommits(ref string) ([]git.Hash, error) {
}
-// ListEntries will return the list of entries in a Git tree
-func (repo *GitRepo) ListEntries(hash git.Hash) ([]TreeEntry, error) {
+// ReadTree will return the list of entries in a Git tree
+func (repo *GitRepo) ReadTree(hash git.Hash) ([]TreeEntry, error) {
stdout, err := repo.runGitCommand("ls-tree", string(hash))
if err != nil {
diff --git a/repository/mock_repo.go b/repository/mock_repo.go
index 04d9355e..cf572d87 100644
--- a/repository/mock_repo.go
+++ b/repository/mock_repo.go
@@ -3,6 +3,7 @@ package repository
import (
"crypto/sha1"
"fmt"
+ "strings"
"github.com/MichaelMure/git-bug/util/git"
"github.com/MichaelMure/git-bug/util/lamport"
@@ -151,12 +152,12 @@ func (r *mockRepoForTest) CopyRef(source string, dest string) error {
}
func (r *mockRepoForTest) ListRefs(refspec string) ([]string, error) {
- keys := make([]string, len(r.refs))
+ var keys []string
- i := 0
for k := range r.refs {
- keys[i] = k
- i++
+ if strings.HasPrefix(k, refspec) {
+ keys = append(keys, k)
+ }
}
return keys, nil
@@ -181,7 +182,7 @@ func (r *mockRepoForTest) ListCommits(ref string) ([]git.Hash, error) {
return hashes, nil
}
-func (r *mockRepoForTest) ListEntries(hash git.Hash) ([]TreeEntry, error) {
+func (r *mockRepoForTest) ReadTree(hash git.Hash) ([]TreeEntry, error) {
var data string
data, ok := r.trees[hash]
@@ -205,11 +206,44 @@ func (r *mockRepoForTest) ListEntries(hash git.Hash) ([]TreeEntry, error) {
}
func (r *mockRepoForTest) FindCommonAncestor(hash1 git.Hash, hash2 git.Hash) (git.Hash, error) {
- panic("implement me")
+ ancestor1 := []git.Hash{hash1}
+
+ for hash1 != "" {
+ c, ok := r.commits[hash1]
+ if !ok {
+ return "", fmt.Errorf("unknown commit %v", hash1)
+ }
+ ancestor1 = append(ancestor1, c.parent)
+ hash1 = c.parent
+ }
+
+ for {
+ for _, ancestor := range ancestor1 {
+ if ancestor == hash2 {
+ return ancestor, nil
+ }
+ }
+
+ c, ok := r.commits[hash2]
+ if !ok {
+ return "", fmt.Errorf("unknown commit %v", hash1)
+ }
+
+ if c.parent == "" {
+ return "", fmt.Errorf("no ancestor found")
+ }
+
+ hash2 = c.parent
+ }
}
func (r *mockRepoForTest) GetTreeHash(commit git.Hash) (git.Hash, error) {
- panic("implement me")
+ c, ok := r.commits[commit]
+ if !ok {
+ return "", fmt.Errorf("unknown commit")
+ }
+
+ return c.treeHash, nil
}
func (r *mockRepoForTest) GetOrCreateClock(name string) (lamport.Clock, error) {
diff --git a/repository/repo.go b/repository/repo.go
index 561fc1c5..13bcca4f 100644
--- a/repository/repo.go
+++ b/repository/repo.go
@@ -66,12 +66,21 @@ type Repo interface {
// StoreTree will store a mapping key-->Hash as a Git tree
StoreTree(mapping []TreeEntry) (git.Hash, error)
+ // ReadTree will return the list of entries in a Git tree
+ ReadTree(hash git.Hash) ([]TreeEntry, error)
+
// StoreCommit will store a Git commit with the given Git tree
StoreCommit(treeHash git.Hash) (git.Hash, error)
// StoreCommit will store a Git commit with the given Git tree
StoreCommitWithParent(treeHash git.Hash, parent git.Hash) (git.Hash, error)
+ // GetTreeHash return the git tree hash referenced in a commit
+ GetTreeHash(commit git.Hash) (git.Hash, error)
+
+ // FindCommonAncestor will return the last common ancestor of two chain of commit
+ FindCommonAncestor(hash1 git.Hash, hash2 git.Hash) (git.Hash, error)
+
// UpdateRef will create or update a Git reference
UpdateRef(ref string, hash git.Hash) error
@@ -86,15 +95,6 @@ type Repo interface {
// ListCommits will return the list of tree hashes of a ref, in chronological order
ListCommits(ref string) ([]git.Hash, error)
-
- // ListEntries will return the list of entries in a Git tree
- ListEntries(hash git.Hash) ([]TreeEntry, error)
-
- // FindCommonAncestor will return the last common ancestor of two chain of commit
- FindCommonAncestor(hash1 git.Hash, hash2 git.Hash) (git.Hash, error)
-
- // GetTreeHash return the git tree hash referenced in a commit
- GetTreeHash(commit git.Hash) (git.Hash, error)
}
// ClockedRepo is a Repo that also has Lamport clocks
diff --git a/repository/repo_testing.go b/repository/repo_testing.go
index 43bbaf14..01d69572 100644
--- a/repository/repo_testing.go
+++ b/repository/repo_testing.go
@@ -2,12 +2,15 @@ package repository
import (
"log"
+ "math/rand"
"os"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+
+ "github.com/MichaelMure/git-bug/util/git"
)
func CleanupTestRepos(repos ...Repo) {
@@ -46,19 +49,125 @@ type RepoCleaner func(repos ...Repo)
// Test suite for a Repo implementation
func RepoTest(t *testing.T, creator RepoCreator, cleaner RepoCleaner) {
- t.Run("Read/Write data", func(t *testing.T) {
+ t.Run("Blob-Tree-Commit-Ref", func(t *testing.T) {
repo := creator(false)
defer cleaner(repo)
- data := []byte("hello")
+ // Blob
+
+ data := randomData()
+
+ blobHash1, err := repo.StoreData(data)
+ require.NoError(t, err)
+ assert.True(t, blobHash1.IsValid())
+
+ blob1Read, err := repo.ReadData(blobHash1)
+ require.NoError(t, err)
+ assert.Equal(t, data, blob1Read)
+
+ // Tree
+
+ blobHash2, err := repo.StoreData(randomData())
+ require.NoError(t, err)
+ blobHash3, err := repo.StoreData(randomData())
+ require.NoError(t, err)
+
+ tree1 := []TreeEntry{
+ {
+ ObjectType: Blob,
+ Hash: blobHash1,
+ Name: "blob1",
+ },
+ {
+ ObjectType: Blob,
+ Hash: blobHash2,
+ Name: "blob2",
+ },
+ }
+
+ treeHash1, err := repo.StoreTree(tree1)
+ require.NoError(t, err)
+ assert.True(t, treeHash1.IsValid())
+
+ tree1Read, err := repo.ReadTree(treeHash1)
+ require.NoError(t, err)
+ assert.ElementsMatch(t, tree1, tree1Read)
+
+ tree2 := []TreeEntry{
+ {
+ ObjectType: Tree,
+ Hash: treeHash1,
+ Name: "tree1",
+ },
+ {
+ ObjectType: Blob,
+ Hash: blobHash3,
+ Name: "blob3",
+ },
+ }
+
+ treeHash2, err := repo.StoreTree(tree2)
+ require.NoError(t, err)
+ assert.True(t, treeHash2.IsValid())
+
+ tree2Read, err := repo.ReadTree(treeHash2)
+ require.NoError(t, err)
+ assert.ElementsMatch(t, tree2, tree2Read)
+
+ // Commit
+
+ commit1, err := repo.StoreCommit(treeHash1)
+ require.NoError(t, err)
+ assert.True(t, commit1.IsValid())
+
+ treeHash1Read, err := repo.GetTreeHash(commit1)
+ require.NoError(t, err)
+ assert.Equal(t, treeHash1, treeHash1Read)
+
+ commit2, err := repo.StoreCommitWithParent(treeHash2, commit1)
+ require.NoError(t, err)
+ assert.True(t, commit2.IsValid())
+
+ treeHash2Read, err := repo.GetTreeHash(commit2)
+ require.NoError(t, err)
+ assert.Equal(t, treeHash2, treeHash2Read)
+
+ // Ref
+
+ exist1, err := repo.RefExist("refs/bugs/ref1")
+ require.NoError(t, err)
+ assert.False(t, exist1)
+
+ err = repo.UpdateRef("refs/bugs/ref1", commit2)
+ require.NoError(t, err)
+
+ exist1, err = repo.RefExist("refs/bugs/ref1")
+ require.NoError(t, err)
+ assert.True(t, exist1)
- h, err := repo.StoreData(data)
+ ls, err := repo.ListRefs("refs/bugs")
require.NoError(t, err)
- assert.NotEmpty(t, h)
+ assert.Equal(t, []string{"refs/bugs/ref1"}, ls)
- read, err := repo.ReadData(h)
+ err = repo.CopyRef("refs/bugs/ref1", "refs/bugs/ref2")
require.NoError(t, err)
- assert.Equal(t, data, read)
+
+ ls, err = repo.ListRefs("refs/bugs")
+ require.NoError(t, err)
+ assert.Equal(t, []string{"refs/bugs/ref1", "refs/bugs/ref2"}, ls)
+
+ commits, err := repo.ListCommits("refs/bugs/ref2")
+ require.NoError(t, err)
+ assert.Equal(t, []git.Hash{commit1, commit2}, commits)
+
+ // Graph
+
+ commit3, err := repo.StoreCommitWithParent(treeHash1, commit1)
+ require.NoError(t, err)
+
+ ancestorHash, err := repo.FindCommonAncestor(commit2, commit3)
+ require.NoError(t, err)
+ assert.Equal(t, commit1, ancestorHash)
})
t.Run("Local config", func(t *testing.T) {
@@ -68,3 +177,12 @@ func RepoTest(t *testing.T, creator RepoCreator, cleaner RepoCleaner) {
testConfig(t, repo.LocalConfig())
})
}
+
+func randomData() []byte {
+ var letterRunes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ b := make([]byte, 32)
+ for i := range b {
+ b[i] = letterRunes[rand.Intn(len(letterRunes))]
+ }
+ return b
+}