0
0
mirror of https://github.com/go-gitea/gitea.git synced 2025-07-20 10:28:36 +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() blob := entry.Blob()
if blob.Size() >= setting.UI.MaxDisplayFileSize {
ctx.NotFound(err)
return
}
buf, dataRc, fInfo, err := getFileReader(ctx, ctx.Repo.Repository.ID, blob) buf, dataRc, fInfo, err := getFileReader(ctx, ctx.Repo.Repository.ID, blob)
if err != nil { if err != nil {
@ -303,6 +299,11 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
operation = "create" 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{ if _, err := files_service.ChangeRepoFiles(ctx, ctx.Repo.Repository, ctx.Doer, &files_service.ChangeRepoFilesOptions{
LastCommitID: form.LastCommit, LastCommitID: form.LastCommit,
OldBranch: ctx.Repo.BranchName, OldBranch: ctx.Repo.BranchName,
@ -313,7 +314,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
Operation: operation, Operation: operation,
FromTreePath: ctx.Repo.TreePath, FromTreePath: ctx.Repo.TreePath,
TreePath: form.TreePath, TreePath: form.TreePath,
ContentReader: strings.NewReader(strings.ReplaceAll(form.Content, "\r", "")), ContentReader: contentReader,
}, },
}, },
Signoff: form.Signoff, Signoff: form.Signoff,

View File

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

View File

@ -10,6 +10,7 @@ import (
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
project_model "code.gitea.io/gitea/models/project" 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/structs"
"code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/modules/web/middleware"
"code.gitea.io/gitea/services/context" "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 // EditRepoFileForm form for changing repository file
type EditRepoFileForm struct { type EditRepoFileForm struct {
TreePath string `binding:"Required;MaxSize(500)"` TreePath string `binding:"Required;MaxSize(500)"`
Content string Content optional.Option[string]
CommitSummary string `binding:"MaxSize(100)"` CommitSummary string `binding:"MaxSize(100)"`
CommitMessage string CommitMessage string
CommitChoice string `binding:"Required;MaxSize(50)"` CommitChoice string `binding:"Required;MaxSize(50)"`

View File

@ -43,7 +43,7 @@ type ChangeRepoFile struct {
Operation string Operation string
TreePath string TreePath string
FromTreePath string FromTreePath string
ContentReader io.ReadSeeker ContentReader io.ReadSeeker // nil if the operation is a pure rename
SHA string SHA string
Options *RepoFileOptions Options *RepoFileOptions
} }
@ -461,6 +461,11 @@ func handleCheckErrors(file *ChangeRepoFile, commit *git.Commit, opts *ChangeRep
// CreateOrUpdateFile handles creating or updating a file for ChangeRepoFiles // 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 { 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 // 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) filesInIndex, err := t.LsFiles(ctx, file.TreePath, file.FromTreePath)
if err != nil { 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 var lfsMetaObject *git_model.LFSMetaObject
if setting.LFS.StartServer && hasOldBranch { if setting.LFS.StartServer && hasOldBranch {
// Check there is no way this can return multiple infos // 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{ attributesMap, err := attribute.CheckAttributes(ctx, t.gitRepo, "" /* use temp repo's working dir */, attribute.CheckAttributeOpts{
Attributes: []string{attribute.Filter}, Attributes: []string{attribute.Filter},
Filenames: []string{file.Options.treePath}, Filenames: []string{file.Options.treePath, file.Options.fromTreePath},
}) })
if err != nil { if err != nil {
return err return err
} }
if attributesMap[file.Options.treePath] != nil && attributesMap[file.Options.treePath].Get(attribute.Filter).ToString().Value() == "lfs" { var pointer *lfs.Pointer
// OK so we are supposed to LFS this data! // Get existing lfs pointer if the old tree path is in lfs
pointer, err := lfs.GeneratePointer(treeObjectContentReader) 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 { if err != nil {
return err 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()) 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 return err
} }
if !exist { if !exist {
_, err := file.ContentReader.Seek(0, io.SeekStart) var lfsContentReader io.Reader
if err != nil { if file.ContentReader != nil {
return err _, 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 { 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) return fmt.Errorf("unable to remove failed inserted LFS object %s: %v (Prev Error: %w)", lfsMetaObject.Oid, err2, err)
} }