mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-01 20:59:45 +09:00
fix(git): reindex go-git storage when a concurrent repack removes packs (#39510)
Improve the go-git workaround to fix these flakes: - https://github.com/go-gitea/gitea/actions/runs/36721877142/job/109908823684 - https://github.com/go-gitea/gitea/actions/runs/36799665163/job/110170983591
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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 <a@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)
|
||||
|
||||
Reference in New Issue
Block a user