Skip to content

Commit

Permalink
fix: use the latest git-lfs-transfer and update implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
aymanbagabas committed Jul 31, 2024
1 parent 6e5452d commit bb59bee
Showing 1 changed file with 23 additions and 49 deletions.
72 changes: 23 additions & 49 deletions pkg/git/lfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"errors"
"fmt"
"io"
"io/fs"
"path"
"path/filepath"
"strconv"
Expand Down Expand Up @@ -60,10 +59,7 @@ func LFSTransfer(ctx context.Context, cmd ServiceCommand) error {
}

// Advertise capabilities.
for _, cap := range []string{
"version=1",
"locking",
} {
for _, cap := range transfer.Capabilities {
if err := handler.WritePacketText(cap); err != nil {
logger.Errorf("error sending capability: %s: %v", cap, err)
return err
Expand Down Expand Up @@ -114,34 +110,32 @@ func (t *lfsTransfer) Batch(_ string, pointers []transfer.BatchItem, _ transfer.
}

// Download implements transfer.Backend.
func (t *lfsTransfer) Download(oid string, _ transfer.Args) (fs.File, error) {
func (t *lfsTransfer) Download(oid string, _ transfer.Args) (io.ReadCloser, int64, error) {
cfg := config.FromContext(t.ctx)
repoID := strconv.FormatInt(t.repo.ID(), 10)
strg := storage.NewLocalStorage(filepath.Join(cfg.DataPath, "lfs", repoID))
pointer := transfer.Pointer{Oid: oid}
return strg.Open(path.Join("objects", pointer.RelativePath()))
}

type uploadObject struct {
oid string
size int64
object storage.Object
}

func (u *uploadObject) Close() error {
return u.object.Close()
obj, err := strg.Open(path.Join("objects", pointer.RelativePath()))
if err != nil {
return nil, 0, err
}
stat, err := obj.Stat()
if err != nil {
return nil, 0, err
}
return obj, stat.Size(), nil
}

// StartUpload implements transfer.Backend.
func (t *lfsTransfer) StartUpload(oid string, r io.Reader, _ transfer.Args) (io.Closer, error) {
// Upload implements transfer.Backend.
func (t *lfsTransfer) Upload(oid string, size int64, r io.Reader, _ transfer.Args) error {
if r == nil {
return nil, fmt.Errorf("no reader: %w", transfer.ErrMissingData)
return fmt.Errorf("no reader: %w", transfer.ErrMissingData)
}

tempDir := "incomplete"
randBytes := make([]byte, 12)
if _, err := rand.Read(randBytes); err != nil {
return nil, err
return err
}

tempName := fmt.Sprintf("%s%x", oid, randBytes)
Expand All @@ -150,45 +144,30 @@ func (t *lfsTransfer) StartUpload(oid string, r io.Reader, _ transfer.Args) (io.
written, err := t.storage.Put(tempName, r)
if err != nil {
t.logger.Errorf("error putting object: %v", err)
return nil, err
return err
}

obj, err := t.storage.Open(tempName)
if err != nil {
t.logger.Errorf("error opening object: %v", err)
return nil, err
}

return &uploadObject{
oid: oid,
size: written,
object: obj,
}, nil
}

// FinishUpload implements transfer.Backend.
func (t *lfsTransfer) FinishUpload(state io.Closer, args transfer.Args) error {
upl, ok := state.(*uploadObject)
if !ok {
return errors.New("invalid state")
return err
}

size, _ := transfer.SizeFromArgs(args)
pointer := transfer.Pointer{
Oid: upl.oid,
Oid: oid,
}
if size > 0 {
pointer.Size = size
} else {
pointer.Size = upl.size
pointer.Size = written
}

if err := t.store.CreateLFSObject(t.ctx, t.dbx, t.repo.ID(), pointer.Oid, pointer.Size); err != nil {
return db.WrapError(err)
}

expectedPath := path.Join("objects", pointer.RelativePath())
if err := t.storage.Rename(upl.object.Name(), expectedPath); err != nil {
if err := t.storage.Rename(obj.Name(), expectedPath); err != nil {
t.logger.Errorf("error renaming object: %v", err)
_ = t.store.DeleteLFSObjectByOid(t.ctx, t.dbx, t.repo.ID(), pointer.Oid)
return err
Expand All @@ -198,12 +177,7 @@ func (t *lfsTransfer) FinishUpload(state io.Closer, args transfer.Args) error {
}

// Verify implements transfer.Backend.
func (t *lfsTransfer) Verify(oid string, args transfer.Args) (transfer.Status, error) {
expectedSize, err := transfer.SizeFromArgs(args)
if err != nil {
return transfer.NewStatus(transfer.StatusBadRequest, "missing size"), nil // nolint: nilerr
}

func (t *lfsTransfer) Verify(oid string, size int64, args transfer.Args) (transfer.Status, error) {
obj, err := t.store.GetLFSObjectByOid(t.ctx, t.dbx, t.repo.ID(), oid)
if err != nil {
if errors.Is(err, db.ErrRecordNotFound) {
Expand All @@ -213,8 +187,8 @@ func (t *lfsTransfer) Verify(oid string, args transfer.Args) (transfer.Status, e
return nil, err
}

if obj.Size != expectedSize {
t.logger.Errorf("size mismatch: %d != %d", obj.Size, expectedSize)
if obj.Size != size {
t.logger.Errorf("size mismatch: %d != %d", obj.Size, size)
return transfer.NewStatus(transfer.StatusConflict, "size mismatch"), nil
}

Expand Down

0 comments on commit bb59bee

Please sign in to comment.