code.gitea.io/gitea@v1.19.3/modules/git/repo_base_gogit.go (about)

     1  // Copyright 2015 The Gogs Authors. All rights reserved.
     2  // Copyright 2017 The Gitea Authors. All rights reserved.
     3  // SPDX-License-Identifier: MIT
     4  
     5  //go:build gogit
     6  
     7  package git
     8  
     9  import (
    10  	"context"
    11  	"errors"
    12  	"path/filepath"
    13  
    14  	gitealog "code.gitea.io/gitea/modules/log"
    15  	"code.gitea.io/gitea/modules/setting"
    16  
    17  	"github.com/go-git/go-billy/v5/osfs"
    18  	gogit "github.com/go-git/go-git/v5"
    19  	"github.com/go-git/go-git/v5/plumbing/cache"
    20  	"github.com/go-git/go-git/v5/storage/filesystem"
    21  )
    22  
    23  // Repository represents a Git repository.
    24  type Repository struct {
    25  	Path string
    26  
    27  	tagCache *ObjectCache
    28  
    29  	gogitRepo    *gogit.Repository
    30  	gogitStorage *filesystem.Storage
    31  	gpgSettings  *GPGSettings
    32  
    33  	Ctx             context.Context
    34  	LastCommitCache *LastCommitCache
    35  }
    36  
    37  // openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext.
    38  func openRepositoryWithDefaultContext(repoPath string) (*Repository, error) {
    39  	return OpenRepository(DefaultContext, repoPath)
    40  }
    41  
    42  // OpenRepository opens the repository at the given path within the context.Context
    43  func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
    44  	repoPath, err := filepath.Abs(repoPath)
    45  	if err != nil {
    46  		return nil, err
    47  	} else if !isDir(repoPath) {
    48  		return nil, errors.New("no such file or directory")
    49  	}
    50  
    51  	fs := osfs.New(repoPath)
    52  	_, err = fs.Stat(".git")
    53  	if err == nil {
    54  		fs, err = fs.Chroot(".git")
    55  		if err != nil {
    56  			return nil, err
    57  		}
    58  	}
    59  	storage := filesystem.NewStorageWithOptions(fs, cache.NewObjectLRUDefault(), filesystem.Options{KeepDescriptors: true, LargeObjectThreshold: setting.Git.LargeObjectThreshold})
    60  	gogitRepo, err := gogit.Open(storage, fs)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	return &Repository{
    66  		Path:         repoPath,
    67  		gogitRepo:    gogitRepo,
    68  		gogitStorage: storage,
    69  		tagCache:     newObjectCache(),
    70  		Ctx:          ctx,
    71  	}, nil
    72  }
    73  
    74  // Close this repository, in particular close the underlying gogitStorage if this is not nil
    75  func (repo *Repository) Close() (err error) {
    76  	if repo == nil || repo.gogitStorage == nil {
    77  		return
    78  	}
    79  	if err := repo.gogitStorage.Close(); err != nil {
    80  		gitealog.Error("Error closing storage: %v", err)
    81  	}
    82  	repo.LastCommitCache = nil
    83  	repo.tagCache = nil
    84  	return
    85  }
    86  
    87  // GoGitRepo gets the go-git repo representation
    88  func (repo *Repository) GoGitRepo() *gogit.Repository {
    89  	return repo.gogitRepo
    90  }