0
0
mirror of https://github.com/go-gitea/gitea.git synced 2025-07-20 01:48:28 +02:00

Fix empty binary content after move

This commit is contained in:
bytedream 2025-05-05 17:10:08 +02:00
parent 07845a262d
commit 6f3b69b900
4 changed files with 78 additions and 18 deletions

View File

@ -145,10 +145,6 @@ func editFile(ctx *context.Context, isNewFile bool) {
}
blob := entry.Blob()
if blob.Size() >= setting.UI.MaxDisplayFileSize {
ctx.NotFound(err)
return
}
buf, dataRc, fInfo, err := getFileReader(ctx, ctx.Repo.Repository.ID, blob)
if err != nil {
@ -303,6 +299,11 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
operation = "create"
}
var contentReader io.ReadSeeker
if isNewFile && form.Content.Has() {
contentReader = strings.NewReader(strings.ReplaceAll(form.Content.Value(), "\r", ""))
}
if _, err := files_service.ChangeRepoFiles(ctx, ctx.Repo.Repository, ctx.Doer, &files_service.ChangeRepoFilesOptions{
LastCommitID: form.LastCommit,
OldBranch: ctx.Repo.BranchName,
@ -313,7 +314,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
Operation: operation,
FromTreePath: ctx.Repo.TreePath,
TreePath: form.TreePath,
ContentReader: strings.NewReader(strings.ReplaceAll(form.Content, "\r", "")),
ContentReader: contentReader,
},
},
Signoff: form.Signoff,

View File

@ -99,7 +99,7 @@ func NewDiffPatchPost(ctx *context.Context) {
OldBranch: ctx.Repo.BranchName,
NewBranch: branchName,
Message: message,
Content: strings.ReplaceAll(form.Content, "\r", ""),
Content: strings.ReplaceAll(form.Content.Value(), "\r", ""),
Author: gitCommitter,
Committer: gitCommitter,
})

View File

@ -10,6 +10,7 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
project_model "code.gitea.io/gitea/models/project"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web/middleware"
"code.gitea.io/gitea/services/context"
@ -689,7 +690,7 @@ func (f *NewWikiForm) Validate(req *http.Request, errs binding.Errors) binding.E
// EditRepoFileForm form for changing repository file
type EditRepoFileForm struct {
TreePath string `binding:"Required;MaxSize(500)"`
Content string
Content optional.Option[string]
CommitSummary string `binding:"MaxSize(100)"`
CommitMessage string
CommitChoice string `binding:"Required;MaxSize(50)"`

View File

@ -43,7 +43,7 @@ type ChangeRepoFile struct {
Operation string
TreePath string
FromTreePath string
ContentReader io.ReadSeeker
ContentReader io.ReadSeeker // nil if the operation is a pure rename
SHA string
Options *RepoFileOptions
}
@ -461,6 +461,11 @@ func handleCheckErrors(file *ChangeRepoFile, commit *git.Commit, opts *ChangeRep
// CreateOrUpdateFile handles creating or updating a file for ChangeRepoFiles
func CreateOrUpdateFile(ctx context.Context, t *TemporaryUploadRepository, file *ChangeRepoFile, contentStore *lfs.ContentStore, repoID int64, hasOldBranch bool) error {
// ContentReader is only allowed to be nil if the file is moving
if file.ContentReader == nil && file.TreePath == file.FromTreePath {
return nil
}
// Get the two paths (might be the same if not moving) from the index if they exist
filesInIndex, err := t.LsFiles(ctx, file.TreePath, file.FromTreePath)
if err != nil {
@ -488,26 +493,69 @@ func CreateOrUpdateFile(ctx context.Context, t *TemporaryUploadRepository, file
}
}
treeObjectContentReader := file.ContentReader
var treeObjectContentReader io.Reader = file.ContentReader
var oldEntry *git.TreeEntry
// If nil, use the existing content
if file.ContentReader == nil {
lastCommit, _ := t.GetLastCommit(ctx)
commit, err := t.GetCommit(lastCommit)
if err != nil {
return err
}
oldEntry, err = commit.GetTreeEntryByPath(file.Options.fromTreePath)
if err != nil {
return err
}
treeObjectContentReader, err = oldEntry.Blob().DataAsync()
if err != nil {
return err
}
}
var lfsMetaObject *git_model.LFSMetaObject
if setting.LFS.StartServer && hasOldBranch {
// Check there is no way this can return multiple infos
attributesMap, err := attribute.CheckAttributes(ctx, t.gitRepo, "" /* use temp repo's working dir */, attribute.CheckAttributeOpts{
Attributes: []string{attribute.Filter},
Filenames: []string{file.Options.treePath},
Filenames: []string{file.Options.treePath, file.Options.fromTreePath},
})
if err != nil {
return err
}
if attributesMap[file.Options.treePath] != nil && attributesMap[file.Options.treePath].Get(attribute.Filter).ToString().Value() == "lfs" {
// OK so we are supposed to LFS this data!
pointer, err := lfs.GeneratePointer(treeObjectContentReader)
var pointer *lfs.Pointer
// Get existing lfs pointer if the old tree path is in lfs
if oldEntry != nil && attributesMap[file.Options.fromTreePath] != nil && attributesMap[file.Options.fromTreePath].Get(attribute.Filter).ToString().Value() == "lfs" {
pointerReader, err := oldEntry.Blob().DataAsync()
if err != nil {
return err
}
lfsMetaObject = &git_model.LFSMetaObject{Pointer: pointer, RepositoryID: repoID}
p, err := lfs.ReadPointer(pointerReader)
if err != nil {
return err
}
pointer = &p
}
if attributesMap[file.Options.treePath] != nil && attributesMap[file.Options.treePath].Get(attribute.Filter).ToString().Value() == "lfs" {
// Only generate a new lfs pointer if the old tree path isn't in lfs or the object content is changed
if pointer == nil {
p, err := lfs.GeneratePointer(treeObjectContentReader)
if err != nil {
return err
}
pointer = &p
}
lfsMetaObject = &git_model.LFSMetaObject{Pointer: *pointer, RepositoryID: repoID}
treeObjectContentReader = strings.NewReader(pointer.StringContent())
} else if pointer != nil { // old tree path was in lfs, new is not
treeObjectContentReader, err = lfs.ReadMetaObject(*pointer)
if err != nil {
return err
}
}
}
@ -539,11 +587,21 @@ func CreateOrUpdateFile(ctx context.Context, t *TemporaryUploadRepository, file
return err
}
if !exist {
_, err := file.ContentReader.Seek(0, io.SeekStart)
if err != nil {
return err
var lfsContentReader io.Reader
if file.ContentReader != nil {
_, err := file.ContentReader.Seek(0, io.SeekStart)
if err != nil {
return err
}
lfsContentReader = file.ContentReader
} else {
lfsContentReader, err = oldEntry.Blob().DataAsync()
if err != nil {
return err
}
}
if err := contentStore.Put(lfsMetaObject.Pointer, file.ContentReader); err != nil {
if err := contentStore.Put(lfsMetaObject.Pointer, lfsContentReader); err != nil {
if _, err2 := git_model.RemoveLFSMetaObjectByOid(ctx, repoID, lfsMetaObject.Oid); err2 != nil {
return fmt.Errorf("unable to remove failed inserted LFS object %s: %v (Prev Error: %w)", lfsMetaObject.Oid, err2, err)
}