2019-04-17 19:06:35 +03:00
// 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 repofiles
import (
"fmt"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
2019-05-11 13:21:34 +03:00
api "code.gitea.io/gitea/modules/structs"
2019-04-17 19:06:35 +03:00
)
// 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 ( ) )
2019-06-12 22:41:28 +03:00
if err != nil {
return nil , err
}
2019-04-17 19:06:35 +03:00
gitTree , err := gitRepo . GetTree ( sha )
if err != nil || gitTree == nil {
return nil , models . ErrSHANotFound {
SHA : sha ,
}
}
tree := new ( api . GitTreeResponse )
2019-05-03 03:33:11 +03:00
tree . SHA = gitTree . ResolvedID . String ( )
2019-04-17 19:06:35 +03:00
tree . URL = repo . APIURL ( ) + "/git/trees/" + 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 )
2019-06-12 22:41:28 +03:00
copy ( blobURL , apiURL )
2019-04-17 19:06:35 +03:00
copy ( blobURL [ apiURLLen : ] , "/git/blobs/" )
// 51 is len(sha1) + len("/git/trees/"). 40 + 11.
treeURL := make ( [ ] byte , apiURLLen + 51 )
2019-06-12 22:41:28 +03:00
copy ( treeURL , apiURL )
2019-04-17 19:06:35 +03:00
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
2019-04-19 15:17:27 +03:00
tree . Entries [ e ] . Path = entries [ e ] . Name ( )
tree . Entries [ e ] . Mode = fmt . Sprintf ( "%06o" , entries [ e ] . Mode ( ) )
tree . Entries [ e ] . Type = entries [ e ] . Type ( )
tree . Entries [ e ] . Size = entries [ e ] . Size ( )
tree . Entries [ e ] . SHA = entries [ e ] . ID . String ( )
2019-04-17 19:06:35 +03:00
if entries [ e ] . IsDir ( ) {
copy ( treeURL [ copyPos : ] , entries [ e ] . ID . String ( ) )
2019-06-12 22:41:28 +03:00
tree . Entries [ i ] . URL = string ( treeURL )
2019-04-17 19:06:35 +03:00
} else {
copy ( blobURL [ copyPos : ] , entries [ e ] . ID . String ( ) )
2019-06-12 22:41:28 +03:00
tree . Entries [ i ] . URL = string ( blobURL )
2019-04-17 19:06:35 +03:00
}
}
return tree , nil
}