code.gitea.io/gitea@v1.19.3/modules/git/repo_base_nogogit.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  	"bufio"
    11  	"context"
    12  	"errors"
    13  	"path/filepath"
    14  
    15  	"code.gitea.io/gitea/modules/log"
    16  )
    17  
    18  // Repository represents a Git repository.
    19  type Repository struct {
    20  	Path string
    21  
    22  	tagCache *ObjectCache
    23  
    24  	gpgSettings *GPGSettings
    25  
    26  	batchCancel context.CancelFunc
    27  	batchReader *bufio.Reader
    28  	batchWriter WriteCloserError
    29  
    30  	checkCancel context.CancelFunc
    31  	checkReader *bufio.Reader
    32  	checkWriter WriteCloserError
    33  
    34  	Ctx             context.Context
    35  	LastCommitCache *LastCommitCache
    36  }
    37  
    38  // openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext.
    39  func openRepositoryWithDefaultContext(repoPath string) (*Repository, error) {
    40  	return OpenRepository(DefaultContext, repoPath)
    41  }
    42  
    43  // OpenRepository opens the repository at the given path with the provided context.
    44  func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
    45  	repoPath, err := filepath.Abs(repoPath)
    46  	if err != nil {
    47  		return nil, err
    48  	} else if !isDir(repoPath) {
    49  		return nil, errors.New("no such file or directory")
    50  	}
    51  
    52  	// Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
    53  	if err := EnsureValidGitRepository(ctx, repoPath); err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	repo := &Repository{
    58  		Path:     repoPath,
    59  		tagCache: newObjectCache(),
    60  		Ctx:      ctx,
    61  	}
    62  
    63  	repo.batchWriter, repo.batchReader, repo.batchCancel = CatFileBatch(ctx, repoPath)
    64  	repo.checkWriter, repo.checkReader, repo.checkCancel = CatFileBatchCheck(ctx, repo.Path)
    65  
    66  	return repo, nil
    67  }
    68  
    69  // CatFileBatch obtains a CatFileBatch for this repository
    70  func (repo *Repository) CatFileBatch(ctx context.Context) (WriteCloserError, *bufio.Reader, func()) {
    71  	if repo.batchCancel == nil || repo.batchReader.Buffered() > 0 {
    72  		log.Debug("Opening temporary cat file batch for: %s", repo.Path)
    73  		return CatFileBatch(ctx, repo.Path)
    74  	}
    75  	return repo.batchWriter, repo.batchReader, func() {}
    76  }
    77  
    78  // CatFileBatchCheck obtains a CatFileBatchCheck for this repository
    79  func (repo *Repository) CatFileBatchCheck(ctx context.Context) (WriteCloserError, *bufio.Reader, func()) {
    80  	if repo.checkCancel == nil || repo.checkReader.Buffered() > 0 {
    81  		log.Debug("Opening temporary cat file batch-check: %s", repo.Path)
    82  		return CatFileBatchCheck(ctx, repo.Path)
    83  	}
    84  	return repo.checkWriter, repo.checkReader, func() {}
    85  }
    86  
    87  // Close this repository, in particular close the underlying gogitStorage if this is not nil
    88  func (repo *Repository) Close() (err error) {
    89  	if repo == nil {
    90  		return
    91  	}
    92  	if repo.batchCancel != nil {
    93  		repo.batchCancel()
    94  		repo.batchReader = nil
    95  		repo.batchWriter = nil
    96  		repo.batchCancel = nil
    97  	}
    98  	if repo.checkCancel != nil {
    99  		repo.checkCancel()
   100  		repo.checkCancel = nil
   101  		repo.checkReader = nil
   102  		repo.checkWriter = nil
   103  	}
   104  	repo.LastCommitCache = nil
   105  	repo.tagCache = nil
   106  	return err
   107  }