2024-08-12 17:16:55 +02:00
// Copyright 2015 The Gogs Authors. All rights reserved.
// Copyright 2017 The Gitea Authors. All rights reserved.
2022-11-27 13:20:29 -05:00
// SPDX-License-Identifier: MIT
2022-01-19 23:26:57 +00:00
package git
2024-08-12 17:16:55 +02:00
import (
"bufio"
"context"
"errors"
"path/filepath"
"code.gitea.io/gitea/modules/log"
)
// Repository represents a Git repository.
type Repository struct {
Path string
tagCache * ObjectCache
gpgSettings * GPGSettings
batchInUse bool
batchCancel context . CancelFunc
batchReader * bufio . Reader
batchWriter WriteCloserError
checkInUse bool
checkCancel context . CancelFunc
checkReader * bufio . Reader
checkWriter WriteCloserError
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 with the provided 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" )
}
// 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!
if err := EnsureValidGitRepository ( ctx , repoPath ) ; err != nil {
return nil , err
}
repo := & Repository {
Path : repoPath ,
tagCache : newObjectCache ( ) ,
Ctx : ctx ,
}
repo . batchWriter , repo . batchReader , repo . batchCancel = CatFileBatch ( ctx , repoPath )
repo . checkWriter , repo . checkReader , repo . checkCancel = CatFileBatchCheck ( ctx , repoPath )
return repo , nil
}
// CatFileBatch obtains a CatFileBatch for this repository
func ( repo * Repository ) CatFileBatch ( ctx context . Context ) ( WriteCloserError , * bufio . Reader , func ( ) ) {
if repo . batchCancel == nil || repo . batchInUse {
log . Debug ( "Opening temporary cat file batch for: %s" , repo . Path )
return CatFileBatch ( ctx , repo . Path )
}
repo . batchInUse = true
return repo . batchWriter , repo . batchReader , func ( ) {
repo . batchInUse = false
}
}
// CatFileBatchCheck obtains a CatFileBatchCheck for this repository
func ( repo * Repository ) CatFileBatchCheck ( ctx context . Context ) ( WriteCloserError , * bufio . Reader , func ( ) ) {
if repo . checkCancel == nil || repo . checkInUse {
log . Debug ( "Opening temporary cat file batch-check for: %s" , repo . Path )
return CatFileBatchCheck ( ctx , repo . Path )
}
repo . checkInUse = true
return repo . checkWriter , repo . checkReader , func ( ) {
repo . checkInUse = false
}
}
func ( repo * Repository ) Close ( ) error {
if repo == nil {
return nil
}
if repo . batchCancel != nil {
repo . batchCancel ( )
repo . batchReader = nil
repo . batchWriter = nil
repo . batchCancel = nil
repo . batchInUse = false
}
if repo . checkCancel != nil {
repo . checkCancel ( )
repo . checkCancel = nil
repo . checkReader = nil
repo . checkWriter = nil
repo . checkInUse = false
}
repo . LastCommitCache = nil
repo . tagCache = nil
return nil
}