0
0
Fork 0
mirror of https://github.com/go-gitea/gitea synced 2025-01-17 07:02:34 +01:00
gitea/modules/git/repo_base_gogit.go
zeripath 5cb0c9aa0d
Propagate context and ensure git commands run in request context ()
This PR continues the work in  by progressively ensuring that git
commands run within the request context.

This now means that the if there is a git repo already open in the context it will be used instead of reopening it.

Signed-off-by: Andrew Thornton <art27@cantab.net>
2022-01-19 23:26:57 +00:00

89 lines
2.3 KiB
Go

// Copyright 2015 The Gogs Authors. All rights reserved.
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
//go:build gogit
// +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/osfs"
gogit "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/cache"
"github.com/go-git/go-git/v5/storage/filesystem"
)
// Repository represents a Git repository.
type Repository struct {
Path string
tagCache *ObjectCache
gogitRepo *gogit.Repository
gogitStorage *filesystem.Storage
gpgSettings *GPGSettings
Ctx context.Context
}
// OpenRepository opens the repository at the given path.
func OpenRepository(repoPath string) (*Repository, error) {
return OpenRepositoryCtx(DefaultContext, repoPath)
}
// OpenRepositoryCtx opens the repository at the given path within the context.Context
func OpenRepositoryCtx(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
}
}
storage := filesystem.NewStorageWithOptions(fs, cache.NewObjectLRUDefault(), filesystem.Options{KeepDescriptors: true, LargeObjectThreshold: setting.Git.LargeObjectThreshold})
gogitRepo, err := gogit.Open(storage, fs)
if err != nil {
return nil, err
}
return &Repository{
Path: repoPath,
gogitRepo: gogitRepo,
gogitStorage: storage,
tagCache: newObjectCache(),
Ctx: ctx,
}, nil
}
// Close this repository, in particular close the underlying gogitStorage if this is not nil
func (repo *Repository) Close() (err error) {
if repo == nil || repo.gogitStorage == nil {
return
}
if err := repo.gogitStorage.Close(); err != nil {
gitealog.Error("Error closing storage: %v", err)
}
return
}
// GoGitRepo gets the go-git repo representation
func (repo *Repository) GoGitRepo() *gogit.Repository {
return repo.gogitRepo
}