mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-02 20:06:06 +01:00 
			
		
		
		
	This PR continues the work in #17125 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>
		
			
				
	
	
		
			90 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			90 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
 | 
						|
}
 |