mirror of
https://gitcode.com/gitea/gitea.git
synced 2025-06-04 03:09:34 +08:00
.gitea
.github
assets
build
cmd
contrib
custom
docker
docs
models
modules
activitypub
analyze
appstate
auth
avatar
base
cache
charset
container
context
convert
csv
doctor
emoji
eventsource
generate
git
gitgraph
graceful
hcaptcha
highlight
hostmatcher
httpcache
httplib
indexer
issue
json
lfs
LICENSE
client.go
client_test.go
content_store.go
endpoint.go
endpoint_test.go
filesystem_client.go
http_client.go
http_client_test.go
pointer.go
pointer_scanner_gogit.go
pointer_scanner_nogogit.go
pointer_test.go
shared.go
transferadapter.go
transferadapter_test.go
log
markup
mcaptcha
metrics
migration
mirror
nosql
notification
options
packages
paginator
password
pprof
private
process
proxy
proxyprotocol
public
queue
recaptcha
references
regexplru
repository
secret
session
setting
sitemap
ssh
storage
structs
svg
sync
templates
test
timeutil
translation
typesniffer
updatechecker
upload
uri
user
util
validation
watcher
web
options
public
routers
services
snap
templates
tests
tools
web_src
.air.toml
.changelog.yml
.drone.yml
.editorconfig
.eslintrc.yaml
.gitattributes
.gitignore
.golangci.yml
.ignore
.lgtm
.markdownlint.yaml
.npmrc
.spectral.yaml
.stylelintrc.yaml
BSDmakefile
CHANGELOG.md
CONTRIBUTING.md
DCO
Dockerfile
Dockerfile.rootless
LICENSE
MAINTAINERS
Makefile
README.md
README_ZH.md
SECURITY.md
build.go
go.mod
go.sum
jest.config.js
main.go
package-lock.json
package.json
playwright.config.js
webpack.config.js

* Added push mirror model. * Integrated push mirror into queue. * Moved methods into own file. * Added basic implementation. * Mirror wiki too. * Removed duplicated method. * Get url for different remotes. * Added migration. * Unified remote url access. * Add/Remove push mirror remotes. * Prevent hangs with missing credentials. * Moved code between files. * Changed sanitizer interface. * Added push mirror backend methods. * Only update the mirror remote. * Limit refs on push. * Added UI part. * Added missing table. * Delete mirror if repository gets removed. * Changed signature. Handle object errors. * Added upload method. * Added "upload" unit tests. * Added transfer adapter unit tests. * Send correct headers. * Added pushing of LFS objects. * Added more logging. * Simpler body handling. * Process files in batches to reduce HTTP calls. * Added created timestamp. * Fixed invalid column name. * Changed name to prevent xorm auto setting. * Remove table header im empty. * Strip exit code from error message. * Added docs page about mirroring. * Fixed date. * Fixed merge errors. * Moved test to integrations. * Added push mirror test. * Added test.
94 lines
1.9 KiB
Go
94 lines
1.9 KiB
Go
// Copyright 2021 The Gitea Authors. All rights reserved.
|
|
// Use of this source code is governed by a MIT-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package lfs
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"net/url"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"code.gitea.io/gitea/modules/util"
|
|
)
|
|
|
|
// FilesystemClient is used to read LFS data from a filesystem path
|
|
type FilesystemClient struct {
|
|
lfsdir string
|
|
}
|
|
|
|
// BatchSize returns the preferred size of batchs to process
|
|
func (c *FilesystemClient) BatchSize() int {
|
|
return 1
|
|
}
|
|
|
|
func newFilesystemClient(endpoint *url.URL) *FilesystemClient {
|
|
path, _ := util.FileURLToPath(endpoint)
|
|
|
|
lfsdir := filepath.Join(path, "lfs", "objects")
|
|
|
|
client := &FilesystemClient{lfsdir}
|
|
|
|
return client
|
|
}
|
|
|
|
func (c *FilesystemClient) objectPath(oid string) string {
|
|
return filepath.Join(c.lfsdir, oid[0:2], oid[2:4], oid)
|
|
}
|
|
|
|
// Download reads the specific LFS object from the target path
|
|
func (c *FilesystemClient) Download(ctx context.Context, objects []Pointer, callback DownloadCallback) error {
|
|
for _, object := range objects {
|
|
p := Pointer{object.Oid, object.Size}
|
|
|
|
objectPath := c.objectPath(p.Oid)
|
|
|
|
f, err := os.Open(objectPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := callback(p, f, nil); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Upload writes the specific LFS object to the target path
|
|
func (c *FilesystemClient) Upload(ctx context.Context, objects []Pointer, callback UploadCallback) error {
|
|
for _, object := range objects {
|
|
p := Pointer{object.Oid, object.Size}
|
|
|
|
objectPath := c.objectPath(p.Oid)
|
|
|
|
if err := os.MkdirAll(filepath.Dir(objectPath), os.ModePerm); err != nil {
|
|
return err
|
|
}
|
|
|
|
content, err := callback(p, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = func() error {
|
|
defer content.Close()
|
|
|
|
f, err := os.Create(objectPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = io.Copy(f, content)
|
|
|
|
return err
|
|
}()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|