Browse Source

update

tags/v1.22.5.1^2
open_test 3 years ago
parent
commit
bc2e442132
2 changed files with 143 additions and 101 deletions
  1. +139
    -101
      modules/repofiles/update.go
  2. +4
    -0
      routers/repo/editor.go

+ 139
- 101
modules/repofiles/update.go View File

@@ -9,6 +9,7 @@ import (
"container/list"
"fmt"
"path"
"regexp"
"strings"
"time"

@@ -866,17 +867,42 @@ func RenameRepoFile(repo *models.Repository, doer *models.User, opts *RenameRepo
// haven't been made. We throw an error if one wasn't provided.
return models.ErrSHAOrCommitIDNotProvided{}
}
//获取

// If a lastCommitID was given and it doesn't match the commitID of the head of the branch throw
// an error, but only if we aren't creating a new branch.
if commit.ID.String() != opts.LastCommitID {
if changed, err := commit.FileChangedSinceCommit(fromTreePath, opts.LastCommitID); err != nil {
return err
} else if changed {
return models.ErrCommitIDDoesNotMatch{
GivenCommitID: opts.LastCommitID,
CurrentCommitID: opts.LastCommitID,
}
}
// The file wasn't modified, so we are good to delete it
}

entry, err := commit.GetTreeEntryByPath(treePath)
if err == nil || (!git.IsErrNotExist(err) && !entry.IsDir()) {
// Means the file has been exist in new path
return models.ErrFilePathInvalid{
Message: fmt.Sprintf("a file exists where you’re trying to create a subdirectory [path: %s]", treePath),
Path: treePath,
Name: treePath,
Type: git.EntryModeBlob,
}
}

if fromTreeEntry.IsDir() {
tree, err := commit.Tree.SubTree(fromTreePath)
if err != nil {
return err
}
if err := moveAndAddDir(fromTreePath, treePath, opts.LastCommitID, tree, commit, t); err != nil {
if err := moveAndAddDir(fromTreePath, treePath, opts.BranchName, tree, commit, t); err != nil {
return err
}
} else {
if err := moveAndAddFile(opts.FromTreePath, opts.TreePath, opts.LastCommitID, commit, t); err != nil {
if err := moveAndAddFile(opts.FromTreePath, opts.TreePath, entry, t); err != nil {
return err
}
}
@@ -902,120 +928,132 @@ func RenameRepoFile(repo *models.Repository, doer *models.User, opts *RenameRepo
return nil
}

func moveAndAddDir(oldTreePath, newTreePath, lastCommitID string, currentTree *git.Tree, currentBranchCommit *git.Commit, t *TemporaryUploadRepository) error {
entries, err := currentTree.ListEntries()
if err != nil {
return err
}
for _, v := range entries {
if v.IsDir() {
subTree, err := currentTree.SubTree(v.Name())
if err != nil {
return err
}
if err := moveAndAddDir(path.Join(oldTreePath, v.Name()), path.Join(newTreePath, v.Name()), lastCommitID, subTree, currentBranchCommit, t); err != nil {
return err
}
} else {
if err := moveAndAddFile(path.Join(oldTreePath, v.Name()), path.Join(newTreePath, v.Name()), lastCommitID, currentBranchCommit, t); err != nil {
return err
}
}
}
return nil
}
func moveAndAddDir(oldTreePath, newTreePath, branchName string, currentTree *git.Tree, currentBranchCommit *git.Commit, t *TemporaryUploadRepository) error {

func moveAndAddFile(oldTreePath, newTreePath, lastCommitID string, currentBranchCommit *git.Commit, t *TemporaryUploadRepository) error {
fromEntry, err := currentBranchCommit.GetTreeEntryByPath(oldTreePath)
if err != nil {
return err
}
// If a lastCommitID was given and it doesn't match the commitID of the head of the branch throw
// an error, but only if we aren't creating a new branch.
if currentBranchCommit.ID.String() != lastCommitID {
if changed, err := currentBranchCommit.FileChangedSinceCommit(oldTreePath, lastCommitID); err != nil {
return err
} else if changed {
return models.ErrCommitIDDoesNotMatch{
GivenCommitID: lastCommitID,
CurrentCommitID: lastCommitID,
}
}
// The file wasn't modified, so we are good to delete it
}
executable := fromEntry.IsExecutable()
//if _, err := git.NewCommand("checkout", branchName).RunInDir(t.basePath); err != nil {
// return fmt.Errorf("moveAndAddFile: %v", err)
//}
//获取oldTreePath的objectHash
//s, err := git.NewCommand("cat-file", "-p", fmt.Sprint(currentTree.ID)).RunInDir(t.basePath)
//if err != nil {
// return fmt.Errorf("moveAndAddFile: %v", err)
//}
//objectHash, err := t.HashObject(strings.NewReader(s))
objectHash := fmt.Sprint(currentTree.ID)

// For the path where this file will be created/updated, we need to make
// sure no parts of the path are existing files or links except for the last
// item in the path which is the file name, and that shouldn't exist IF it is
// a new file OR is being moved to a new path.
treePathParts := strings.Split(newTreePath, "/")
subTreePath := ""
for index, part := range treePathParts {
subTreePath = path.Join(subTreePath, part)
entry, err := currentBranchCommit.GetTreeEntryByPath(subTreePath)
if err != nil {
if git.IsErrNotExist(err) {
// Means there is no item with that name, so we're good
break
}
return err
}
if index < len(treePathParts)-1 {
if !entry.IsDir() {
return models.ErrFilePathInvalid{
Message: fmt.Sprintf("a file exists where you’re trying to create a subdirectory [path: %s]", subTreePath),
Path: subTreePath,
Name: part,
Type: git.EntryModeBlob,
}
}
} else if entry.IsLink() {
return models.ErrFilePathInvalid{
Message: fmt.Sprintf("a symbolic link exists where you’re trying to create a subdirectory [path: %s]", subTreePath),
Path: subTreePath,
Name: part,
Type: git.EntryModeSymlink,
}
} else if entry.IsDir() {
// Add the object to the index
if _, err := git.NewCommand("update-index", "--add", "--cacheinfo", "40000", objectHash, newTreePath).RunInDir(t.basePath); err != nil {
stderr := err.Error()
if matched, _ := regexp.MatchString(".*Invalid path '.*", stderr); matched {
return models.ErrFilePathInvalid{
Message: fmt.Sprintf("a directory exists where you’re trying to create a file [path: %s]", subTreePath),
Path: subTreePath,
Name: part,
Type: git.EntryModeTree,
Message: newTreePath,
Path: newTreePath,
}
}
log.Error("Unable to add object to index: %s %s %s in temporary repo %s(%s) Error: %v", "40000", objectHash, newTreePath, t.repo.FullName(), t.basePath, err)
return fmt.Errorf("Unable to add object to index at %s in temporary repo %s Error: %v", newTreePath, t.repo.FullName(), err)
}
//if err := t.AddObjectToIndex("40000", objectHash, newTreePath); err != nil {
// return err
//}
//entries, err := currentTree.ListEntries()
//if err != nil {
// return err
//}
//for _, v := range entries {
// tempNewPath := path.Join(newTreePath, v.Name())
// tempOldPath := path.Join(oldTreePath, v.Name())
// fromEntry, err := currentBranchCommit.GetTreeEntryByPath(tempOldPath)
// if err != nil {
// return err
// }
//
// //if v.IsDir() {
// // subTree, err := currentTree.SubTree(v.Name())
// // if err != nil {
// // return err
// // }
// // if err := moveAndAddDir(tempOldPath, tempNewPath, branchName, subTree, currentBranchCommit, t); err != nil {
// // return err
// // }
// //} else {
// if err := moveAndAddFile(tempOldPath, tempNewPath, fromEntry, t); err != nil {
// return err
// }
// //}
//
// //if v.IsDir() {
// // subTree, err := currentTree.SubTree(v.Name())
// // if err != nil {
// // return err
// // }
// // if err := moveAndAddDir(path.Join(oldTreePath, v.Name()), path.Join(newTreePath, v.Name()), lastCommitID, subTree, currentBranchCommit, t); err != nil {
// // return err
// // }
// //} else {
// // if err := moveAndAddFile(path.Join(oldTreePath, v.Name()), path.Join(newTreePath, v.Name()), lastCommitID, currentBranchCommit, t); err != nil {
// // return err
// // }
// //}
//}

}
return nil
}

// Get the two paths (might be the same if not moving) from the index if they exist
filesInIndex, err := t.LsFiles(newTreePath, oldTreePath)
if err != nil {
return fmt.Errorf("UpdateRepoFile: %v", err)
}
func moveAndAddFile(oldTreePath, newTreePath string, fromEntry *git.TreeEntry, t *TemporaryUploadRepository) error {
//if _, err := git.NewCommand("mv", oldTreePath, newTreePath).RunInDir(t.basePath); err != nil {
// return fmt.Errorf("moveAndAddFile: %v", err)
//}

// Remove the old path from the tree
if len(filesInIndex) > 0 {
for _, file := range filesInIndex {
if file == oldTreePath {
if err := t.RemoveFilesFromIndex(oldTreePath); err != nil {
return err
}
}
}
}
executable := fromEntry.IsExecutable()
stdOut := new(bytes.Buffer)
stdErr := new(bytes.Buffer)
stdIn := new(bytes.Buffer)
stdIn.WriteString("0 0000000000000000000000000000000000000000\t")
stdIn.WriteString(oldTreePath)
stdIn.WriteByte('\000')

if err := git.NewCommand("update-index", "--remove", "-z", "--index-info").RunInDirFullPipeline(t.basePath, stdOut, stdErr, stdIn); err != nil {
log.Error("Unable to update-index for temporary repo: %s (%s) Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), t.basePath, err, stdOut.String(), stdErr.String())
return fmt.Errorf("Unable to update-index for temporary repo: %s Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), err, stdOut.String(), stdErr.String())
}
//
//if _, err := git.NewCommand("update-index", "--remove", "-z", "index-info", oldTreePath).RunInDir(t.basePath); err != nil {
// log.Error("Unable to update-index for temporary repo: %s (%s) Error: %v\n", t.repo.FullName(), t.basePath, err)
// return fmt.Errorf("Unable to update-index for temporary repo: %s Error: %v\n", t.repo.FullName(), err)
//}
//if err := t.RemoveFilesFromIndex(oldTreePath); err != nil {
// return err
//}

//获取oldTreePath的objectHash
objectHash := fmt.Sprint(fromEntry.Blob().ID)

// Add the object to the index
if executable {
if err := t.AddObjectToIndex("100755", objectHash, newTreePath); err != nil {
if fromEntry.IsDir() {
if _, err := git.NewCommand("update-index", "--add", "--cacheinfo", "40000", objectHash, newTreePath).RunInDir(t.basePath); err != nil {
stderr := err.Error()
if matched, _ := regexp.MatchString(".*Invalid path '.*", stderr); matched {
return models.ErrFilePathInvalid{
Message: newTreePath,
Path: newTreePath,
}
}
log.Error("Unable to add object to index: %s %s %s in temporary repo %s(%s) Error: %v", "40000", objectHash, newTreePath, t.repo.FullName(), t.basePath, err)
return fmt.Errorf("Unable to add object to index at %s in temporary repo %s Error: %v", newTreePath, t.repo.FullName(), err)
}
if err := t.AddObjectToIndex("40000", objectHash, newTreePath); err != nil {
return err
}
} else {
if err := t.AddObjectToIndex("100644", objectHash, newTreePath); err != nil {
return err
if executable {
if err := t.AddObjectToIndex("100755", objectHash, newTreePath); err != nil {
return err
}
} else {
if err := t.AddObjectToIndex("100644", objectHash, newTreePath); err != nil {
return err
}
}
}
return nil


+ 4
- 0
routers/repo/editor.go View File

@@ -808,6 +808,10 @@ func renameFilePost(ctx *context.Context, form auth.RenameRepoFileForm) {
ctx.JSON(http.StatusOK, response.ServerError("param error"))
return
}
if form.TreePath == ctx.Repo.TreePath {
ctx.JSON(http.StatusOK, response.Success())
return
}

canCommit := renderCommitRights(ctx)
branchName := ctx.Repo.BranchName


Loading…
Cancel
Save