You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

repo_base_gogit.go 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2017 The Gitea Authors. All rights reserved.
  3. // SPDX-License-Identifier: MIT
  4. //go:build gogit
  5. package git
  6. import (
  7. "context"
  8. "path/filepath"
  9. gitealog "code.gitea.io/gitea/modules/log"
  10. "code.gitea.io/gitea/modules/setting"
  11. "code.gitea.io/gitea/modules/util"
  12. "github.com/go-git/go-billy/v5"
  13. "github.com/go-git/go-billy/v5/osfs"
  14. gogit "github.com/go-git/go-git/v5"
  15. "github.com/go-git/go-git/v5/plumbing"
  16. "github.com/go-git/go-git/v5/plumbing/cache"
  17. "github.com/go-git/go-git/v5/storage/filesystem"
  18. )
  19. const isGogit = true
  20. // Repository represents a Git repository.
  21. type Repository struct {
  22. Path string
  23. tagCache *ObjectCache
  24. gogitRepo *gogit.Repository
  25. gogitStorage *filesystem.Storage
  26. gpgSettings *GPGSettings
  27. Ctx context.Context
  28. LastCommitCache *LastCommitCache
  29. objectFormat ObjectFormat
  30. }
  31. // openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext.
  32. func openRepositoryWithDefaultContext(repoPath string) (*Repository, error) {
  33. return OpenRepository(DefaultContext, repoPath)
  34. }
  35. // OpenRepository opens the repository at the given path within the context.Context
  36. func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
  37. repoPath, err := filepath.Abs(repoPath)
  38. if err != nil {
  39. return nil, err
  40. } else if !isDir(repoPath) {
  41. return nil, util.NewNotExistErrorf("no such file or directory")
  42. }
  43. fs := osfs.New(repoPath)
  44. _, err = fs.Stat(".git")
  45. if err == nil {
  46. fs, err = fs.Chroot(".git")
  47. if err != nil {
  48. return nil, err
  49. }
  50. }
  51. // the "clone --shared" repo doesn't work well with go-git AlternativeFS, https://github.com/go-git/go-git/issues/1006
  52. // so use "/" for AlternatesFS, I guess it is the same behavior as current nogogit (no limitation or check for the "objects/info/alternates" paths), trust the "clone" command executed by the server.
  53. var altFs billy.Filesystem
  54. if setting.IsWindows {
  55. altFs = osfs.New(filepath.VolumeName(setting.RepoRootPath) + "\\") // TODO: does it really work for Windows? Need some time to check.
  56. } else {
  57. altFs = osfs.New("/")
  58. }
  59. storage := filesystem.NewStorageWithOptions(fs, cache.NewObjectLRUDefault(), filesystem.Options{KeepDescriptors: true, LargeObjectThreshold: setting.Git.LargeObjectThreshold, AlternatesFS: altFs})
  60. gogitRepo, err := gogit.Open(storage, fs)
  61. if err != nil {
  62. return nil, err
  63. }
  64. return &Repository{
  65. Path: repoPath,
  66. gogitRepo: gogitRepo,
  67. gogitStorage: storage,
  68. tagCache: newObjectCache(),
  69. Ctx: ctx,
  70. objectFormat: ParseGogitHash(plumbing.ZeroHash).Type(),
  71. }, nil
  72. }
  73. // Close this repository, in particular close the underlying gogitStorage if this is not nil
  74. func (repo *Repository) Close() error {
  75. if repo == nil || repo.gogitStorage == nil {
  76. return nil
  77. }
  78. if err := repo.gogitStorage.Close(); err != nil {
  79. gitealog.Error("Error closing storage: %v", err)
  80. }
  81. repo.gogitStorage = nil
  82. repo.LastCommitCache = nil
  83. repo.tagCache = nil
  84. return nil
  85. }
  86. // GoGitRepo gets the go-git repo representation
  87. func (repo *Repository) GoGitRepo() *gogit.Repository {
  88. return repo.gogitRepo
  89. }