This commit is contained in:
Jason Song 2024-07-27 13:35:55 +08:00 committed by GitHub
commit d613e2396e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 46 additions and 4 deletions

View File

@ -136,14 +136,13 @@ func (c *HTTPClient) performOperation(ctx context.Context, objects []Pointer, dc
for _, object := range result.Objects { for _, object := range result.Objects {
if object.Error != nil { if object.Error != nil {
objectError := errors.New(object.Error.Message) log.Trace("Error on object %v: %v", object.Pointer, object.Error)
log.Trace("Error on object %v: %v", object.Pointer, objectError)
if uc != nil { if uc != nil {
if _, err := uc(object.Pointer, objectError); err != nil { if _, err := uc(object.Pointer, object.Error); err != nil {
return err return err
} }
} else { } else {
if err := dc(object.Pointer, nil, objectError); err != nil { if err := dc(object.Pointer, nil, object.Error); err != nil {
return err return err
} }
} }

View File

@ -4,7 +4,11 @@
package lfs package lfs
import ( import (
"errors"
"fmt"
"time" "time"
"code.gitea.io/gitea/modules/util"
) )
const ( const (
@ -64,6 +68,39 @@ type ObjectError struct {
Message string `json:"message"` Message string `json:"message"`
} }
var (
// See https://github.com/git-lfs/git-lfs/blob/main/docs/api/batch.md#successful-responses
// LFS object error codes should match HTTP status codes where possible:
// 404 - The object does not exist on the server.
// 409 - The specified hash algorithm disagrees with the server's acceptable options.
// 410 - The object was removed by the owner.
// 422 - Validation error.
ErrObjectNotExist = util.ErrNotExist // the object does not exist on the server
ErrObjectHashMismatch = errors.New("the specified hash algorithm disagrees with the server's acceptable options")
ErrObjectRemoved = errors.New("the object was removed by the owner")
ErrObjectValidation = errors.New("validation error")
)
func (e *ObjectError) Error() string {
return fmt.Sprintf("[%d] %s", e.Code, e.Message)
}
func (e *ObjectError) Unwrap() error {
switch e.Code {
case 404:
return ErrObjectNotExist
case 409:
return ErrObjectHashMismatch
case 410:
return ErrObjectRemoved
case 422:
return ErrObjectValidation
default:
return errors.New(e.Message)
}
}
// PointerBlob associates a Git blob with a Pointer. // PointerBlob associates a Git blob with a Pointer.
type PointerBlob struct { type PointerBlob struct {
Hash string Hash string

View File

@ -5,6 +5,7 @@ package repository
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"io" "io"
"strings" "strings"
@ -181,6 +182,10 @@ func StoreMissingLfsObjectsInRepository(ctx context.Context, repo *repo_model.Re
downloadObjects := func(pointers []lfs.Pointer) error { downloadObjects := func(pointers []lfs.Pointer) error {
err := lfsClient.Download(ctx, pointers, func(p lfs.Pointer, content io.ReadCloser, objectError error) error { err := lfsClient.Download(ctx, pointers, func(p lfs.Pointer, content io.ReadCloser, objectError error) error {
if objectError != nil { if objectError != nil {
if errors.Is(objectError, lfs.ErrObjectNotExist) {
log.Warn("Repo[%-v]: Ignore missing LFS object %-v: %v", repo, p, objectError)
return nil
}
return objectError return objectError
} }

View File

@ -169,6 +169,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
lfsClient := lfs.NewClient(endpoint, httpTransport) lfsClient := lfs.NewClient(endpoint, httpTransport)
if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, repo, gitRepo, lfsClient); err != nil { if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, repo, gitRepo, lfsClient); err != nil {
log.Error("Failed to store missing LFS objects for repository: %v", err) log.Error("Failed to store missing LFS objects for repository: %v", err)
return repo, fmt.Errorf("StoreMissingLfsObjectsInRepository: %w", err)
} }
} }
} }