diff --git a/modules/git/repo_base_gogit.go b/modules/git/repo_base_gogit.go index f9a8efacea3..ef98ac3223b 100644 --- a/modules/git/repo_base_gogit.go +++ b/modules/git/repo_base_gogit.go @@ -20,6 +20,7 @@ import ( "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/cache" "github.com/go-git/go-git/v5/storage/filesystem" + "github.com/go-git/go-git/v5/storage/filesystem/dotgit" ) const isGogit = true @@ -31,8 +32,8 @@ type Repository struct { gogitStorage *reindexingStorage } -// reindexingStorage picks up packs that git wrote after go-git loaded its index -// https://github.com/go-git/go-git/issues/2439 +// reindexingStorage reloads the pack index when git added or removed packs after go-git loaded it +// https://github.com/go-git/go-git/issues/2439 https://github.com/go-git/go-git/issues/1623 type reindexingStorage struct { *filesystem.Storage packs []plumbing.Hash @@ -40,7 +41,7 @@ type reindexingStorage struct { func (s *reindexingStorage) EncodedObject(t plumbing.ObjectType, h plumbing.Hash) (plumbing.EncodedObject, error) { obj, err := s.Storage.EncodedObject(t, h) - if !errors.Is(err, plumbing.ErrObjectNotFound) { + if !errors.Is(err, plumbing.ErrObjectNotFound) && !errors.Is(err, dotgit.ErrPackfileNotFound) { return obj, err } packs, _ := s.ObjectPacks() diff --git a/modules/git/repo_branch_test.go b/modules/git/repo_branch_test.go index d40d826e1a8..8b7613a39f5 100644 --- a/modules/git/repo_branch_test.go +++ b/modules/git/repo_branch_test.go @@ -7,6 +7,8 @@ import ( "path/filepath" "testing" + "gitea.dev/modules/git/gitcmd" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -39,6 +41,26 @@ func TestRepository_GetBranches(t *testing.T) { assert.ElementsMatch(t, []string{}, branches) } +func TestGetBranchNamesAfterRepack(t *testing.T) { + repoDir := t.TempDir() + require.NoError(t, gitcmd.NewCommand("init", "--bare").AddDynamicArguments(repoDir).Run(t.Context())) + for _, from := range []string{"", "from refs/heads/main^0\n"} { + stdin := "commit refs/heads/main\ncommitter a 0 +0000\ndata 0\n" + from + require.NoError(t, gitcmd.NewCommand("fast-import").WithDir(repoDir).WithStdinBytes([]byte(stdin)).Run(t.Context())) + require.NoError(t, gitcmd.NewCommand("repack", "-d").WithDir(repoDir).Run(t.Context())) + } + + repo, err := OpenRepositoryLocal(t.Context(), repoDir) + require.NoError(t, err) + defer repo.Close() + require.False(t, repo.IsObjectExist(t.Context(), "0000000000000000000000000000000000000001")) + require.NoError(t, gitcmd.NewCommand("repack", "-a", "-d").WithDir(repoDir).Run(t.Context())) + + branches, _, err := repo.GetBranchNames(t.Context(), 0, 0) + require.NoError(t, err) + assert.Equal(t, []string{"main"}, branches) +} + func BenchmarkRepository_GetBranches(b *testing.B) { bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") bareRepo1, err := OpenRepositoryLocal(b.Context(), bareRepo1Path)