aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--modules/lfs/http_client.go7
-rw-r--r--modules/lfs/shared.go37
-rw-r--r--modules/repository/repo.go5
-rw-r--r--services/repository/migrate.go1
4 files changed, 46 insertions, 4 deletions
diff --git a/modules/lfs/http_client.go b/modules/lfs/http_client.go
index f5ddd38b09..427f57df2d 100644
--- a/modules/lfs/http_client.go
+++ b/modules/lfs/http_client.go
@@ -136,14 +136,13 @@ func (c *HTTPClient) performOperation(ctx context.Context, objects []Pointer, dc
for _, object := range result.Objects {
if object.Error != nil {
- objectError := errors.New(object.Error.Message)
- log.Trace("Error on object %v: %v", object.Pointer, objectError)
+ log.Trace("Error on object %v: %v", object.Pointer, object.Error)
if uc != nil {
- if _, err := uc(object.Pointer, objectError); err != nil {
+ if _, err := uc(object.Pointer, object.Error); err != nil {
return err
}
} else {
- if err := dc(object.Pointer, nil, objectError); err != nil {
+ if err := dc(object.Pointer, nil, object.Error); err != nil {
return err
}
}
diff --git a/modules/lfs/shared.go b/modules/lfs/shared.go
index 80f4fed00d..aef9e456fc 100644
--- a/modules/lfs/shared.go
+++ b/modules/lfs/shared.go
@@ -4,7 +4,11 @@
package lfs
import (
+ "errors"
+ "fmt"
"time"
+
+ "code.gitea.io/gitea/modules/util"
)
const (
@@ -63,6 +67,39 @@ type ObjectError struct {
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.
type PointerBlob struct {
Hash string
diff --git a/modules/repository/repo.go b/modules/repository/repo.go
index cb926084ba..3d1899b2fe 100644
--- a/modules/repository/repo.go
+++ b/modules/repository/repo.go
@@ -5,6 +5,7 @@ package repository
import (
"context"
+ "errors"
"fmt"
"io"
"strings"
@@ -181,6 +182,10 @@ func StoreMissingLfsObjectsInRepository(ctx context.Context, repo *repo_model.Re
downloadObjects := func(pointers []lfs.Pointer) error {
err := lfsClient.Download(ctx, pointers, func(p lfs.Pointer, content io.ReadCloser, objectError error) error {
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
}
diff --git a/services/repository/migrate.go b/services/repository/migrate.go
index df5cc67ae1..2e901791b4 100644
--- a/services/repository/migrate.go
+++ b/services/repository/migrate.go
@@ -169,6 +169,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
lfsClient := lfs.NewClient(endpoint, httpTransport)
if err = repo_module.StoreMissingLfsObjectsInRepository(ctx, repo, gitRepo, lfsClient); err != nil {
log.Error("Failed to store missing LFS objects for repository: %v", err)
+ return repo, fmt.Errorf("StoreMissingLfsObjectsInRepository: %w", err)
}
}
}