summaryrefslogtreecommitdiffstats
path: root/modules/git/repo_base_gogit.go
diff options
context:
space:
mode:
Diffstat (limited to 'modules/git/repo_base_gogit.go')
-rw-r--r--modules/git/repo_base_gogit.go107
1 files changed, 107 insertions, 0 deletions
diff --git a/modules/git/repo_base_gogit.go b/modules/git/repo_base_gogit.go
new file mode 100644
index 00000000..3ca5eb36
--- /dev/null
+++ b/modules/git/repo_base_gogit.go
@@ -0,0 +1,107 @@
+// Copyright 2015 The Gogs Authors. All rights reserved.
+// Copyright 2017 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+//go:build gogit
+
+package git
+
+import (
+ "context"
+ "errors"
+ "path/filepath"
+
+ gitealog "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+
+ "github.com/go-git/go-billy/v5"
+ "github.com/go-git/go-billy/v5/osfs"
+ gogit "github.com/go-git/go-git/v5"
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/cache"
+ "github.com/go-git/go-git/v5/storage/filesystem"
+)
+
+func init() {
+ isGogit = true
+}
+
+// Repository represents a Git repository.
+type Repository struct {
+ Path string
+
+ tagCache *ObjectCache
+
+ gogitRepo *gogit.Repository
+ gogitStorage *filesystem.Storage
+ gpgSettings *GPGSettings
+
+ Ctx context.Context
+ LastCommitCache *LastCommitCache
+ objectFormat ObjectFormat
+}
+
+// openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext.
+func openRepositoryWithDefaultContext(repoPath string) (*Repository, error) {
+ return OpenRepository(DefaultContext, repoPath)
+}
+
+// OpenRepository opens the repository at the given path within the context.Context
+func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
+ repoPath, err := filepath.Abs(repoPath)
+ if err != nil {
+ return nil, err
+ } else if !isDir(repoPath) {
+ return nil, errors.New("no such file or directory")
+ }
+
+ fs := osfs.New(repoPath)
+ _, err = fs.Stat(".git")
+ if err == nil {
+ fs, err = fs.Chroot(".git")
+ if err != nil {
+ return nil, err
+ }
+ }
+ // the "clone --shared" repo doesn't work well with go-git AlternativeFS, https://github.com/go-git/go-git/issues/1006
+ // so use "/" for AlternatesFS, I guess it is the same behavior as current nogogit (no limitation or check for the "objects/info/alternates" paths), trust the "clone" command executed by the server.
+ var altFs billy.Filesystem
+ if setting.IsWindows {
+ altFs = osfs.New(filepath.VolumeName(setting.RepoRootPath) + "\\") // TODO: does it really work for Windows? Need some time to check.
+ } else {
+ altFs = osfs.New("/")
+ }
+ storage := filesystem.NewStorageWithOptions(fs, cache.NewObjectLRUDefault(), filesystem.Options{KeepDescriptors: true, LargeObjectThreshold: setting.Git.LargeObjectThreshold, AlternatesFS: altFs})
+ gogitRepo, err := gogit.Open(storage, fs)
+ if err != nil {
+ return nil, err
+ }
+
+ return &Repository{
+ Path: repoPath,
+ gogitRepo: gogitRepo,
+ gogitStorage: storage,
+ tagCache: newObjectCache(),
+ Ctx: ctx,
+ objectFormat: ParseGogitHash(plumbing.ZeroHash).Type(),
+ }, nil
+}
+
+// Close this repository, in particular close the underlying gogitStorage if this is not nil
+func (repo *Repository) Close() error {
+ if repo == nil || repo.gogitStorage == nil {
+ return nil
+ }
+ if err := repo.gogitStorage.Close(); err != nil {
+ gitealog.Error("Error closing storage: %v", err)
+ }
+ repo.gogitStorage = nil
+ repo.LastCommitCache = nil
+ repo.tagCache = nil
+ return nil
+}
+
+// GoGitRepo gets the go-git repo representation
+func (repo *Repository) GoGitRepo() *gogit.Repository {
+ return repo.gogitRepo
+}