|
@@ -7,6 +7,7 @@ package lfs
|
|
|
import (
|
|
|
"encoding/json"
|
|
|
"io"
|
|
|
+ "io/ioutil"
|
|
|
"net/http"
|
|
|
"os"
|
|
|
"strconv"
|
|
@@ -63,7 +64,22 @@ func serveBasicDownload(c *context.Context, repo *db.Repository, oid lfsutil.OID
|
|
|
|
|
|
// PUT /{owner}/{repo}.git/info/lfs/object/basic/{oid}
|
|
|
func serveBasicUpload(c *context.Context, repo *db.Repository, oid lfsutil.OID) {
|
|
|
- err := db.LFS.CreateObject(repo.ID, oid, c.Req.Request.Body, lfsutil.StorageLocal)
|
|
|
+ // NOTE: LFS client will retry upload the same object if there was a partial failure,
|
|
|
+ // therefore we would like to skip ones that already exist.
|
|
|
+ _, err := db.LFS.GetObjectByOID(repo.ID, oid)
|
|
|
+ if err == nil {
|
|
|
+ // Object exists, drain the request body and we're good.
|
|
|
+ _, _ = io.Copy(ioutil.Discard, c.Req.Request.Body)
|
|
|
+ c.Req.Request.Body.Close()
|
|
|
+ c.Status(http.StatusOK)
|
|
|
+ return
|
|
|
+ } else if !db.IsErrLFSObjectNotExist(err) {
|
|
|
+ internalServerError(c.Resp)
|
|
|
+ log.Error("Failed to get object [repo_id: %d, oid: %s]: %v", repo.ID, oid, err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ err = db.LFS.CreateObject(repo.ID, oid, c.Req.Request.Body, lfsutil.StorageLocal)
|
|
|
if err != nil {
|
|
|
internalServerError(c.Resp)
|
|
|
log.Error("Failed to create object [repo_id: %d, oid: %s]: %v", repo.ID, oid, err)
|