Skip to content

Commit 2806363

Browse files
committed
Git-Trees API
1 parent d9b0b7f commit 2806363

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

routers/api/v1/api.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,9 @@ func RegisterRoutes(m *macaron.Macaron) {
444444

445445
m.Group("/:username/:reponame", func() {
446446
m.Combo("").Get(repo.Get).Delete(reqToken(), repo.Delete)
447+
m.Group("/git/trees", func() {
448+
m.Combo("/:sha", context.RepoRef()).Get(repo.GetTree)
449+
})
447450
m.Group("/hooks", func() {
448451
m.Combo("").Get(repo.ListHooks).
449452
Post(bind(api.CreateHookOption{}), repo.CreateHook)

routers/api/v1/repo/tree.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright 2018 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package repo
6+
7+
import (
8+
"fmt"
9+
"strings"
10+
11+
"code.gitea.io/gitea/modules/setting"
12+
"code.gitea.io/gitea/modules/context"
13+
"code.gitea.io/git"
14+
"code.gitea.io/sdk/gitea"
15+
)
16+
17+
func GetTree(ctx *context.APIContext) {
18+
sha := ctx.Params("sha")
19+
if len(sha) == 0 {
20+
ctx.Error(400, "sha not provided", nil)
21+
return
22+
}
23+
tree := GetTreeBySHA(ctx, sha)
24+
if tree != nil {
25+
ctx.JSON(200, tree)
26+
} else {
27+
ctx.Error(400, "sha invalid", nil)
28+
}
29+
}
30+
31+
func GetTreeBySHA(ctx *context.APIContext, sha string) *gitea.GitTreeResponse {
32+
gitTree, err := ctx.Repo.GitRepo.GetTree(sha)
33+
if err != nil || gitTree == nil{
34+
return nil
35+
}
36+
tree := new(gitea.GitTreeResponse)
37+
repoID := strings.TrimRight(setting.AppURL, "/") + "/api/v1/repos/" + ctx.Repo.Repository.Owner.Name + "/" + ctx.Repo.Repository.Name
38+
tree.SHA = gitTree.ID.String()
39+
tree.URL = repoID + "/git/trees/" + tree.SHA
40+
var entries git.Entries
41+
if ctx.QueryBool("recursive") {
42+
entries, err = gitTree.ListEntriesRecursive()
43+
} else {
44+
entries, err = gitTree.ListEntries()
45+
}
46+
if err != nil {
47+
return tree
48+
}
49+
repoIDLen := len(repoID)
50+
51+
// 51 is len(sha1) + len("/git/blobs/"). 40 + 11.
52+
blobURL := make([]byte, repoIDLen+ 51)
53+
copy(blobURL[:], repoID)
54+
copy(blobURL[repoIDLen:], "/git/blobs/")
55+
56+
// 51 is len(sha1) + len("/git/trees/"). 40 + 11.
57+
treeURL := make([]byte, repoIDLen+ 51)
58+
copy(treeURL[:], repoID)
59+
copy(treeURL[repoIDLen:], "/git/trees/")
60+
61+
// 40 is the size of the sha1 hash in hexadecimal format.
62+
copyPos := len(treeURL) - 40
63+
64+
if len(entries) > 1000 {
65+
tree.Entries = make([]gitea.GitEntry, 1000)
66+
} else {
67+
tree.Entries = make([]gitea.GitEntry, len(entries))
68+
}
69+
for e := range entries {
70+
if e > 1000 {
71+
tree.Truncated = true
72+
break
73+
}
74+
75+
tree.Entries[e].Path = entries[e].Name()
76+
tree.Entries[e].Mode = fmt.Sprintf("%06x", entries[e].Mode())
77+
tree.Entries[e].Type = string(entries[e].Type)
78+
tree.Entries[e].Size = entries[e].Size()
79+
tree.Entries[e].SHA = entries[e].ID.String()
80+
81+
if entries[e].IsDir() {
82+
copy(treeURL[copyPos:], entries[e].ID.String())
83+
tree.Entries[e].URL = string(treeURL[:])
84+
} else {
85+
copy(blobURL[copyPos:], entries[e].ID.String())
86+
tree.Entries[e].URL = string(blobURL[:])
87+
}
88+
}
89+
return tree
90+
}

0 commit comments

Comments
 (0)