Skip to content

Commit c11aadd

Browse files
committed
fix
# Conflicts: # go.sum # tests/integration/git_lfs_ssh_test.go
1 parent 602af14 commit c11aadd

File tree

3 files changed

+31
-13
lines changed

3 files changed

+31
-13
lines changed

go.mod

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ require (
3535
github.com/bohde/codel v0.2.0
3636
github.com/buildkite/terminal-to-html/v3 v3.16.8
3737
github.com/caddyserver/certmagic v0.24.0
38-
github.com/charmbracelet/git-lfs-transfer v0.2.0
38+
github.com/charmbracelet/git-lfs-transfer v0.1.1-0.20251013092601-6327009efd21
3939
github.com/chi-middleware/proxy v1.1.1
4040
github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21
4141
github.com/djherbis/buffer v1.2.0
@@ -56,7 +56,7 @@ require (
5656
github.com/go-co-op/gocron v1.37.0
5757
github.com/go-enry/go-enry/v2 v2.9.2
5858
github.com/go-git/go-billy/v5 v5.6.2
59-
github.com/go-git/go-git/v5 v5.16.2
59+
github.com/go-git/go-git/v5 v5.16.3
6060
github.com/go-ldap/ldap/v3 v3.4.11
6161
github.com/go-redsync/redsync/v4 v4.13.0
6262
github.com/go-sql-driver/mysql v1.9.3
@@ -121,7 +121,7 @@ require (
121121
golang.org/x/net v0.44.0
122122
golang.org/x/oauth2 v0.30.0
123123
golang.org/x/sync v0.17.0
124-
golang.org/x/sys v0.36.0
124+
golang.org/x/sys v0.37.0
125125
golang.org/x/text v0.30.0
126126
google.golang.org/grpc v1.75.0
127127
google.golang.org/protobuf v1.36.8
@@ -298,9 +298,6 @@ replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1
298298

299299
replace github.com/nektos/act => gitea.com/gitea/act v0.261.7-0.20251003180512-ac6e4b751763
300300

301-
// TODO: the only difference is in `PutObject`: the fork doesn't use `NewVerifyingReader(r, sha256.New(), oid, expectedSize)`, need to figure out why
302-
replace github.com/charmbracelet/git-lfs-transfer => gitea.com/gitea/git-lfs-transfer v0.2.0
303-
304301
replace git.sr.ht/~mariusor/go-xsd-duration => gitea.com/gitea/go-xsd-duration v0.0.0-20220703122237-02e73435a078
305302

306303
exclude github.com/gofrs/uuid v3.2.0+incompatible

modules/lfstransfer/backend/backend.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ func (g *GiteaBackend) Batch(_ string, pointers []transfer.BatchItem, args trans
157157
}
158158

159159
// Download implements transfer.Backend. The returned reader must be closed by the caller.
160-
func (g *GiteaBackend) Download(oid string, args transfer.Args) (io.ReadCloser, int64, error) {
160+
func (g *GiteaBackend) Download(oid string, args transfer.Args) (_ io.ReadCloser, _ int64, retErr error) {
161161
idMapStr, exists := args[argID]
162162
if !exists {
163163
return nil, 0, ErrMissingID
@@ -188,7 +188,15 @@ func (g *GiteaBackend) Download(oid string, args transfer.Args) (io.ReadCloser,
188188
if err != nil {
189189
return nil, 0, fmt.Errorf("failed to get response: %w", err)
190190
}
191-
// no need to close the body here by "defer resp.Body.Close()", see below
191+
// We must return the ReaderCloser but not "ReadAll", to avoid OOM.
192+
// "transfer.Backend" will check io.Closer interface and close the Body reader.
193+
// So only close the Body when error occurs
194+
defer func() {
195+
if retErr != nil {
196+
_ = resp.Body.Close()
197+
}
198+
}()
199+
192200
if resp.StatusCode != http.StatusOK {
193201
return nil, 0, statusCodeToErr(resp.StatusCode)
194202
}
@@ -197,7 +205,6 @@ func (g *GiteaBackend) Download(oid string, args transfer.Args) (io.ReadCloser,
197205
if err != nil {
198206
return nil, 0, fmt.Errorf("failed to parse content length: %w", err)
199207
}
200-
// transfer.Backend will check io.Closer interface and close this Body reader
201208
return resp.Body, respSize, nil
202209
}
203210

tests/integration/git_lfs_ssh_test.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ package integration
55

66
import (
77
"net/url"
8+
"os"
9+
"path/filepath"
810
"slices"
911
"strings"
1012
"sync"
@@ -23,7 +25,8 @@ import (
2325

2426
func TestGitLFSSSH(t *testing.T) {
2527
onGiteaRun(t, func(t *testing.T, u *url.URL) {
26-
dstPath := t.TempDir()
28+
localRepoForUpload := filepath.Join(t.TempDir(), "test-upload")
29+
localRepoForDownload := filepath.Join(t.TempDir(), "test-download")
2730
apiTestContext := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
2831

2932
var mu sync.Mutex
@@ -37,17 +40,24 @@ func TestGitLFSSSH(t *testing.T) {
3740
withKeyFile(t, "my-testing-key", func(keyFile string) {
3841
t.Run("CreateUserKey", doAPICreateUserKey(apiTestContext, "test-key", keyFile))
3942
cloneURL := createSSHUrl(apiTestContext.GitPath(), u)
40-
t.Run("Clone", doGitClone(dstPath, cloneURL))
43+
t.Run("CloneOrigin", doGitClone(localRepoForUpload, cloneURL))
4144

4245
cfg, err := setting.CfgProvider.PrepareSaving()
4346
require.NoError(t, err)
4447
cfg.Section("server").Key("LFS_ALLOW_PURE_SSH").SetValue("true")
4548
setting.LFS.AllowPureSSH = true
4649
require.NoError(t, cfg.Save())
4750

48-
_, _, cmdErr := gitcmd.NewCommand("config", "lfs.sshtransfer", "always").RunStdString(t.Context(), &gitcmd.RunOpts{Dir: dstPath})
51+
_, _, cmdErr := gitcmd.NewCommand("config", "lfs.sshtransfer", "always").
52+
WithDir(localRepoForUpload).
53+
RunStdString(t.Context())
4954
assert.NoError(t, cmdErr)
50-
lfsCommitAndPushTest(t, dstPath, 10)
55+
pushedFiles := lfsCommitAndPushTest(t, localRepoForUpload, 10)
56+
57+
t.Run("CloneLFS", doGitClone(localRepoForDownload, cloneURL))
58+
content, err := os.ReadFile(filepath.Join(localRepoForDownload, pushedFiles[0]))
59+
assert.NoError(t, err)
60+
assert.Len(t, content, 10)
5161
})
5262

5363
countBatch := slices.ContainsFunc(routerCalls, func(s string) bool {
@@ -56,12 +66,16 @@ func TestGitLFSSSH(t *testing.T) {
5666
countUpload := slices.ContainsFunc(routerCalls, func(s string) bool {
5767
return strings.Contains(s, "PUT /api/internal/repo/user2/repo1.git/info/lfs/objects/")
5868
})
69+
countDownload := slices.ContainsFunc(routerCalls, func(s string) bool {
70+
return strings.Contains(s, "GET /api/internal/repo/user2/repo1.git/info/lfs/objects/")
71+
})
5972
nonAPIRequests := slices.ContainsFunc(routerCalls, func(s string) bool {
6073
fields := strings.Fields(s)
6174
return !strings.HasPrefix(fields[1], "/api/")
6275
})
6376
assert.NotZero(t, countBatch)
6477
assert.NotZero(t, countUpload)
78+
assert.NotZero(t, countDownload)
6579
assert.Zero(t, nonAPIRequests)
6680
})
6781
}

0 commit comments

Comments
 (0)