aboutsummaryrefslogtreecommitdiffstats
path: root/repository
diff options
context:
space:
mode:
Diffstat (limited to 'repository')
-rw-r--r--repository/git.go9
-rw-r--r--repository/gogit.go152
-rw-r--r--repository/gogit_config.go6
-rw-r--r--repository/gogit_test.go4
-rw-r--r--repository/keyring.go4
-rw-r--r--repository/repo.go5
6 files changed, 105 insertions, 75 deletions
diff --git a/repository/git.go b/repository/git.go
index 8c319285..e67e12f5 100644
--- a/repository/git.go
+++ b/repository/git.go
@@ -5,7 +5,6 @@ import (
"bytes"
"fmt"
"os"
- "path"
"path/filepath"
"strings"
"sync"
@@ -379,9 +378,7 @@ func (repo *GitRepo) GetOrCreateClock(name string) (lamport.Clock, error) {
repo.clocksMutex.Lock()
defer repo.clocksMutex.Unlock()
- p := path.Join(repo.path, clockPath, name+"-clock")
-
- c, err = lamport.NewPersistedClock(p)
+ c, err = lamport.NewPersistedClock(repo.LocalStorage(), name+"-clock")
if err != nil {
return nil, err
}
@@ -398,9 +395,7 @@ func (repo *GitRepo) getClock(name string) (lamport.Clock, error) {
return c, nil
}
- p := path.Join(repo.path, clockPath, name+"-clock")
-
- c, err := lamport.LoadPersistedClock(p)
+ c, err := lamport.LoadPersistedClock(repo.LocalStorage(), name+"-clock")
if err == nil {
repo.clocks[name] = c
return c, nil
diff --git a/repository/gogit.go b/repository/gogit.go
index 874885db..65c2ab54 100644
--- a/repository/gogit.go
+++ b/repository/gogit.go
@@ -6,20 +6,22 @@ import (
"io/ioutil"
"os"
"os/exec"
- stdpath "path"
"path/filepath"
"sort"
"strings"
"sync"
"time"
+ "github.com/99designs/keyring"
"github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-billy/v5/memfs"
"github.com/go-git/go-billy/v5/osfs"
gogit "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/filemode"
"github.com/go-git/go-git/v5/plumbing/object"
+ "github.com/go-git/go-git/v5/storage/memory"
"github.com/MichaelMure/git-bug/util/lamport"
)
@@ -28,16 +30,18 @@ var _ ClockedRepo = &GoGitRepo{}
var _ TestedRepo = &GoGitRepo{}
type GoGitRepo struct {
- r *gogit.Repository
- path string
+ r *gogit.Repository
+ path string
+ isMemory bool
clocksMutex sync.Mutex
clocks map[string]lamport.Clock
- keyring Keyring
+ keyring Keyring
+ localStorage billy.Filesystem
}
-func NewGoGitRepo(path string, clockLoaders []ClockLoader) (*GoGitRepo, error) {
+func OpenGoGitRepo(path string, clockLoaders []ClockLoader) (*GoGitRepo, error) {
path, err := detectGitPath(path)
if err != nil {
return nil, err
@@ -54,10 +58,12 @@ func NewGoGitRepo(path string, clockLoaders []ClockLoader) (*GoGitRepo, error) {
}
repo := &GoGitRepo{
- r: r,
- path: path,
- clocks: make(map[string]lamport.Clock),
- keyring: k,
+ r: r,
+ path: path,
+ isMemory: false,
+ clocks: make(map[string]lamport.Clock),
+ keyring: k,
+ localStorage: osfs.New(filepath.Join(path, "git-bug")),
}
for _, loader := range clockLoaders {
@@ -79,6 +85,69 @@ func NewGoGitRepo(path string, clockLoaders []ClockLoader) (*GoGitRepo, error) {
return repo, nil
}
+// InitGoGitRepo create a new empty git repo at the given path
+func InitGoGitRepo(path string) (*GoGitRepo, error) {
+ r, err := gogit.PlainInit(path, false)
+ if err != nil {
+ return nil, err
+ }
+
+ k, err := defaultKeyring()
+ if err != nil {
+ return nil, err
+ }
+
+ return &GoGitRepo{
+ r: r,
+ path: filepath.Join(path, ".git"),
+ isMemory: false,
+ clocks: make(map[string]lamport.Clock),
+ keyring: k,
+ localStorage: osfs.New(filepath.Join(path, ".git", "git-bug")),
+ }, nil
+}
+
+// InitBareGoGitRepo create a new --bare empty git repo at the given path
+func InitBareGoGitRepo(path string) (*GoGitRepo, error) {
+ r, err := gogit.PlainInit(path, true)
+ if err != nil {
+ return nil, err
+ }
+
+ k, err := defaultKeyring()
+ if err != nil {
+ return nil, err
+ }
+
+ return &GoGitRepo{
+ r: r,
+ path: path,
+ isMemory: false,
+ clocks: make(map[string]lamport.Clock),
+ keyring: k,
+ localStorage: osfs.New(filepath.Join(path, "git-bug")),
+ }, nil
+}
+
+func InitMemoryGoGitRepo() (*GoGitRepo, error) {
+ r, err := gogit.Init(memory.NewStorage(), nil)
+ if err != nil {
+ return nil, err
+ }
+
+ k := keyring.NewArrayKeyring(nil)
+
+ repo := &GoGitRepo{
+ r: r,
+ isMemory: true,
+ clocks: make(map[string]lamport.Clock),
+ keyring: k,
+ localStorage: memfs.New(),
+ }
+
+ return repo, nil
+}
+
func detectGitPath(path string) (string, error) {
// normalize the path
path, err := filepath.Abs(path)
@@ -87,12 +156,12 @@ func detectGitPath(path string) (string, error) {
}
for {
- fi, err := os.Stat(stdpath.Join(path, ".git"))
+ fi, err := os.Stat(filepath.Join(path, ".git"))
if err == nil {
if !fi.IsDir() {
return "", fmt.Errorf(".git exist but is not a directory")
}
- return stdpath.Join(path, ".git"), nil
+ return filepath.Join(path, ".git"), nil
}
if !os.IsNotExist(err) {
// unknown error
@@ -120,7 +189,7 @@ func isGitDir(path string) (bool, error) {
markers := []string{"HEAD", "objects", "refs"}
for _, marker := range markers {
- _, err := os.Stat(stdpath.Join(path, marker))
+ _, err := os.Stat(filepath.Join(path, marker))
if err == nil {
continue
}
@@ -135,46 +204,6 @@ func isGitDir(path string) (bool, error) {
return true, nil
}
-// InitGoGitRepo create a new empty git repo at the given path
-func InitGoGitRepo(path string) (*GoGitRepo, error) {
- r, err := gogit.PlainInit(path, false)
- if err != nil {
- return nil, err
- }
-
- k, err := defaultKeyring()
- if err != nil {
- return nil, err
- }
-
- return &GoGitRepo{
- r: r,
- path: path + "/.git",
- clocks: make(map[string]lamport.Clock),
- keyring: k,
- }, nil
-}
-
-// InitBareGoGitRepo create a new --bare empty git repo at the given path
-func InitBareGoGitRepo(path string) (*GoGitRepo, error) {
- r, err := gogit.PlainInit(path, true)
- if err != nil {
- return nil, err
- }
-
- k, err := defaultKeyring()
- if err != nil {
- return nil, err
- }
-
- return &GoGitRepo{
- r: r,
- path: path,
- clocks: make(map[string]lamport.Clock),
- keyring: k,
- }, nil
-}
-
// LocalConfig give access to the repository scoped configuration
func (repo *GoGitRepo) LocalConfig() Config {
return newGoGitLocalConfig(repo.r)
@@ -182,10 +211,7 @@ func (repo *GoGitRepo) LocalConfig() Config {
// GlobalConfig give access to the global scoped configuration
func (repo *GoGitRepo) GlobalConfig() Config {
- // TODO: replace that with go-git native implementation once it's supported
- // see: https://github.com/go-git/go-git
- // see: https://github.com/src-d/go-git/issues/760
- return newGoGitGlobalConfig(repo.r)
+ return newGoGitGlobalConfig()
}
// AnyConfig give access to a merged local/global configuration
@@ -270,7 +296,7 @@ func (repo *GoGitRepo) GetRemotes() (map[string]string, error) {
// LocalStorage return a billy.Filesystem giving access to $RepoPath/.git/git-bug
func (repo *GoGitRepo) LocalStorage() billy.Filesystem {
- return osfs.New(repo.path)
+ return repo.localStorage
}
// FetchRefs fetch git refs from a remote
@@ -614,9 +640,7 @@ func (repo *GoGitRepo) GetOrCreateClock(name string) (lamport.Clock, error) {
repo.clocksMutex.Lock()
defer repo.clocksMutex.Unlock()
- p := stdpath.Join(repo.path, clockPath, name+"-clock")
-
- c, err = lamport.NewPersistedClock(p)
+ c, err = lamport.NewPersistedClock(repo.localStorage, name+"-clock")
if err != nil {
return nil, err
}
@@ -633,9 +657,7 @@ func (repo *GoGitRepo) getClock(name string) (lamport.Clock, error) {
return c, nil
}
- p := stdpath.Join(repo.path, clockPath, name+"-clock")
-
- c, err := lamport.LoadPersistedClock(p)
+ c, err := lamport.LoadPersistedClock(repo.localStorage, name+"-clock")
if err == nil {
repo.clocks[name] = c
return c, nil
@@ -664,6 +686,10 @@ func (repo *GoGitRepo) GetLocalRemote() string {
// EraseFromDisk delete this repository entirely from the disk
func (repo *GoGitRepo) EraseFromDisk() error {
+ if repo.isMemory {
+ return nil
+ }
+
path := filepath.Clean(strings.TrimSuffix(repo.path, string(filepath.Separator)+".git"))
// fmt.Println("Cleaning repo:", path)
diff --git a/repository/gogit_config.go b/repository/gogit_config.go
index 2f9a4cc3..ba61adca 100644
--- a/repository/gogit_config.go
+++ b/repository/gogit_config.go
@@ -24,7 +24,11 @@ func newGoGitLocalConfig(repo *gogit.Repository) *goGitConfig {
}
}
-func newGoGitGlobalConfig(repo *gogit.Repository) *goGitConfig {
+func newGoGitGlobalConfig() *goGitConfig {
+ // TODO: replace that with go-git native implementation once it's supported
+ // see: https://github.com/go-git/go-git
+ // see: https://github.com/src-d/go-git/issues/760
+
return &goGitConfig{
ConfigRead: &goGitConfigReader{getConfig: func() (*config.Config, error) {
return config.LoadConfig(config.GlobalScope)
diff --git a/repository/gogit_test.go b/repository/gogit_test.go
index a1f67664..a2bb49b9 100644
--- a/repository/gogit_test.go
+++ b/repository/gogit_test.go
@@ -19,7 +19,7 @@ func TestNewGoGitRepo(t *testing.T) {
_, err = InitGoGitRepo(plainRoot)
require.NoError(t, err)
- plainGitDir := path.Join(plainRoot, ".git")
+ plainGitDir := filepath.Join(plainRoot, ".git")
// Bare
bareRoot, err := ioutil.TempDir("", "")
@@ -52,7 +52,7 @@ func TestNewGoGitRepo(t *testing.T) {
}
for i, tc := range tests {
- r, err := NewGoGitRepo(tc.inPath, nil)
+ r, err := OpenGoGitRepo(tc.inPath, nil)
if tc.err {
require.Error(t, err, i)
diff --git a/repository/keyring.go b/repository/keyring.go
index f690b0b3..4cb3c9ff 100644
--- a/repository/keyring.go
+++ b/repository/keyring.go
@@ -2,7 +2,7 @@ package repository
import (
"os"
- "path"
+ "path/filepath"
"github.com/99designs/keyring"
)
@@ -38,7 +38,7 @@ func defaultKeyring() (Keyring, error) {
ServiceName: "git-bug",
// Fallback encrypted file
- FileDir: path.Join(ucd, "git-bug", "keyring"),
+ FileDir: filepath.Join(ucd, "git-bug", "keyring"),
// As we write the file in the user's config directory, this file should already be protected by the OS against
// other user's access. We actually don't terribly need to protect it further and a password prompt across all
// UI's would be a pain. Therefore we use here a constant password so the file will be unreadable by generic file
diff --git a/repository/repo.go b/repository/repo.go
index d34995f9..d8fe44e6 100644
--- a/repository/repo.go
+++ b/repository/repo.go
@@ -25,6 +25,11 @@ type Repo interface {
RepoStorage
}
+type RepoCommonStorage interface {
+ RepoCommon
+ RepoStorage
+}
+
// ClockedRepo is a Repo that also has Lamport clocks
type ClockedRepo interface {
Repo