diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2021-11-24 15:56:24 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-24 15:56:24 +0800 |
commit | c97d66d23cf14e88514cccb88c393d21db51ab7a (patch) | |
tree | 625857bea77befb61847c01bf17aac1177255787 /services/repository/files/tree.go | |
parent | 754fdd8f9c2b1e4e78d507fd414968334cf586fd (diff) | |
download | gitea-c97d66d23cf14e88514cccb88c393d21db51ab7a.tar.gz gitea-c97d66d23cf14e88514cccb88c393d21db51ab7a.zip |
Move repofiles from modules/repofiles to services/repository/files (#17774)
* Move repofiles from modules to services
* rename services/repository/repofiles -> services/repository/files
* Fix test
Co-authored-by: 6543 <6543@obermui.de>
Diffstat (limited to 'services/repository/files/tree.go')
-rw-r--r-- | services/repository/files/tree.go | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/services/repository/files/tree.go b/services/repository/files/tree.go new file mode 100644 index 0000000000..ede206274e --- /dev/null +++ b/services/repository/files/tree.go @@ -0,0 +1,98 @@ +// Copyright 2019 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 files + +import ( + "fmt" + "net/url" + + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/setting" + api "code.gitea.io/gitea/modules/structs" +) + +// GetTreeBySHA get the GitTreeResponse of a repository using a sha hash. +func GetTreeBySHA(repo *models.Repository, sha string, page, perPage int, recursive bool) (*api.GitTreeResponse, error) { + gitRepo, err := git.OpenRepository(repo.RepoPath()) + if err != nil { + return nil, err + } + defer gitRepo.Close() + gitTree, err := gitRepo.GetTree(sha) + if err != nil || gitTree == nil { + return nil, models.ErrSHANotFound{ + SHA: sha, + } + } + tree := new(api.GitTreeResponse) + tree.SHA = gitTree.ResolvedID.String() + tree.URL = repo.APIURL() + "/git/trees/" + url.PathEscape(tree.SHA) + var entries git.Entries + if recursive { + entries, err = gitTree.ListEntriesRecursive() + } else { + entries, err = gitTree.ListEntries() + } + if err != nil { + return nil, err + } + apiURL := repo.APIURL() + apiURLLen := len(apiURL) + + // 51 is len(sha1) + len("/git/blobs/"). 40 + 11. + blobURL := make([]byte, apiURLLen+51) + copy(blobURL, apiURL) + copy(blobURL[apiURLLen:], "/git/blobs/") + + // 51 is len(sha1) + len("/git/trees/"). 40 + 11. + treeURL := make([]byte, apiURLLen+51) + copy(treeURL, apiURL) + copy(treeURL[apiURLLen:], "/git/trees/") + + // 40 is the size of the sha1 hash in hexadecimal format. + copyPos := len(treeURL) - 40 + + if perPage <= 0 || perPage > setting.API.DefaultGitTreesPerPage { + perPage = setting.API.DefaultGitTreesPerPage + } + if page <= 0 { + page = 1 + } + tree.Page = page + tree.TotalCount = len(entries) + rangeStart := perPage * (page - 1) + if rangeStart >= len(entries) { + return tree, nil + } + var rangeEnd int + if len(entries) > perPage { + tree.Truncated = true + } + if rangeStart+perPage < len(entries) { + rangeEnd = rangeStart + perPage + } else { + rangeEnd = len(entries) + } + tree.Entries = make([]api.GitEntry, rangeEnd-rangeStart) + for e := rangeStart; e < rangeEnd; e++ { + i := e - rangeStart + + tree.Entries[i].Path = entries[e].Name() + tree.Entries[i].Mode = fmt.Sprintf("%06o", entries[e].Mode()) + tree.Entries[i].Type = entries[e].Type() + tree.Entries[i].Size = entries[e].Size() + tree.Entries[i].SHA = entries[e].ID.String() + + if entries[e].IsDir() { + copy(treeURL[copyPos:], entries[e].ID.String()) + tree.Entries[i].URL = string(treeURL) + } else { + copy(blobURL[copyPos:], entries[e].ID.String()) + tree.Entries[i].URL = string(blobURL) + } + } + return tree, nil +} |