mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Git-Trees API (#5403)
* Git-Trees API * update vendor'd libs * added comments to exported function and formatted. * make fmt * update per @lafirks feedback
This commit is contained in:
		
				
					committed by
					
						 techknowlogick
						techknowlogick
					
				
			
			
				
	
			
			
			
						parent
						
							f17524bd0c
						
					
				
				
					commit
					d5d847e5c4
				
			
							
								
								
									
										4
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							| @@ -11,11 +11,11 @@ | |||||||
|  |  | ||||||
| [[projects]] | [[projects]] | ||||||
|   branch = "master" |   branch = "master" | ||||||
|   digest = "1:4d2822cfcdf270183cee220e79e7bba55d5214a9c2bfa9b1fd6c6daaf5016eda" |   digest = "1:aed2bc1c4026233af8ad43cab9d9464a0e3b906d3d058d2d6e814f3e1ddfa528" | ||||||
|   name = "code.gitea.io/sdk" |   name = "code.gitea.io/sdk" | ||||||
|   packages = ["gitea"] |   packages = ["gitea"] | ||||||
|   pruneopts = "NUT" |   pruneopts = "NUT" | ||||||
|   revision = "59ddbdc4be1423ab3d5f30b859193ac0308df147" |   revision = "d95a6e0392218961d1bdd18020290a20bd61b063" | ||||||
|  |  | ||||||
| [[projects]] | [[projects]] | ||||||
|   digest = "1:3fcef06a1a6561955c94af6c7757a6fa37605eb653f0d06ab960e5bb80092195" |   digest = "1:3fcef06a1a6561955c94af6c7757a6fa37605eb653f0d06ab960e5bb80092195" | ||||||
|   | |||||||
| @@ -610,6 +610,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||||
| 				m.Group("/git", func() { | 				m.Group("/git", func() { | ||||||
| 					m.Get("/refs", repo.GetGitAllRefs) | 					m.Get("/refs", repo.GetGitAllRefs) | ||||||
| 					m.Get("/refs/*", repo.GetGitRefs) | 					m.Get("/refs/*", repo.GetGitRefs) | ||||||
|  | 					m.Combo("/trees/:sha", context.RepoRef()).Get(repo.GetTree) | ||||||
| 				}, reqRepoReader(models.UnitTypeCode)) | 				}, reqRepoReader(models.UnitTypeCode)) | ||||||
| 			}, repoAssignment()) | 			}, repoAssignment()) | ||||||
| 		}) | 		}) | ||||||
|   | |||||||
							
								
								
									
										92
									
								
								routers/api/v1/repo/tree.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								routers/api/v1/repo/tree.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | |||||||
|  | // Copyright 2018 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 repo | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
|  | 	"code.gitea.io/git" | ||||||
|  | 	"code.gitea.io/gitea/modules/context" | ||||||
|  | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | 	"code.gitea.io/sdk/gitea" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // GetTree get the tree of a repository. | ||||||
|  | func GetTree(ctx *context.APIContext) { | ||||||
|  | 	sha := ctx.Params("sha") | ||||||
|  | 	if len(sha) == 0 { | ||||||
|  | 		ctx.Error(400, "sha not provided", nil) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	tree := GetTreeBySHA(ctx, sha) | ||||||
|  | 	if tree != nil { | ||||||
|  | 		ctx.JSON(200, tree) | ||||||
|  | 	} else { | ||||||
|  | 		ctx.Error(400, "sha invalid", nil) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetTreeBySHA get the GitTreeResponse of a repository using a sha hash. | ||||||
|  | func GetTreeBySHA(ctx *context.APIContext, sha string) *gitea.GitTreeResponse { | ||||||
|  | 	gitTree, err := ctx.Repo.GitRepo.GetTree(sha) | ||||||
|  | 	if err != nil || gitTree == nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	tree := new(gitea.GitTreeResponse) | ||||||
|  | 	repoID := strings.TrimRight(setting.AppURL, "/") + "/api/v1/repos/" + ctx.Repo.Repository.Owner.Name + "/" + ctx.Repo.Repository.Name | ||||||
|  | 	tree.SHA = gitTree.ID.String() | ||||||
|  | 	tree.URL = repoID + "/git/trees/" + tree.SHA | ||||||
|  | 	var entries git.Entries | ||||||
|  | 	if ctx.QueryBool("recursive") { | ||||||
|  | 		entries, err = gitTree.ListEntriesRecursive() | ||||||
|  | 	} else { | ||||||
|  | 		entries, err = gitTree.ListEntries() | ||||||
|  | 	} | ||||||
|  | 	if err != nil { | ||||||
|  | 		return tree | ||||||
|  | 	} | ||||||
|  | 	repoIDLen := len(repoID) | ||||||
|  |  | ||||||
|  | 	// 51 is len(sha1) + len("/git/blobs/"). 40 + 11. | ||||||
|  | 	blobURL := make([]byte, repoIDLen+51) | ||||||
|  | 	copy(blobURL[:], repoID) | ||||||
|  | 	copy(blobURL[repoIDLen:], "/git/blobs/") | ||||||
|  |  | ||||||
|  | 	// 51 is len(sha1) + len("/git/trees/"). 40 + 11. | ||||||
|  | 	treeURL := make([]byte, repoIDLen+51) | ||||||
|  | 	copy(treeURL[:], repoID) | ||||||
|  | 	copy(treeURL[repoIDLen:], "/git/trees/") | ||||||
|  |  | ||||||
|  | 	// 40 is the size of the sha1 hash in hexadecimal format. | ||||||
|  | 	copyPos := len(treeURL) - 40 | ||||||
|  |  | ||||||
|  | 	if len(entries) > 1000 { | ||||||
|  | 		tree.Entries = make([]gitea.GitEntry, 1000) | ||||||
|  | 	} else { | ||||||
|  | 		tree.Entries = make([]gitea.GitEntry, len(entries)) | ||||||
|  | 	} | ||||||
|  | 	for e := range entries { | ||||||
|  | 		if e > 1000 { | ||||||
|  | 			tree.Truncated = true | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		tree.Entries[e].Path = entries[e].Name() | ||||||
|  | 		tree.Entries[e].Mode = fmt.Sprintf("%06x", entries[e].Mode()) | ||||||
|  | 		tree.Entries[e].Type = string(entries[e].Type) | ||||||
|  | 		tree.Entries[e].Size = entries[e].Size() | ||||||
|  | 		tree.Entries[e].SHA = entries[e].ID.String() | ||||||
|  |  | ||||||
|  | 		if entries[e].IsDir() { | ||||||
|  | 			copy(treeURL[copyPos:], entries[e].ID.String()) | ||||||
|  | 			tree.Entries[e].URL = string(treeURL[:]) | ||||||
|  | 		} else { | ||||||
|  | 			copy(blobURL[copyPos:], entries[e].ID.String()) | ||||||
|  | 			tree.Entries[e].URL = string(blobURL[:]) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return tree | ||||||
|  | } | ||||||
							
								
								
									
										39
									
								
								vendor/code.gitea.io/sdk/gitea/repo_tree.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								vendor/code.gitea.io/sdk/gitea/repo_tree.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | // Copyright 2018 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 gitea | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // GitEntry represents a git tree | ||||||
|  | type GitEntry struct { | ||||||
|  | 	Path string `json:"path"` | ||||||
|  | 	Mode string `json:"mode"` | ||||||
|  | 	Type string `json:"type"` | ||||||
|  | 	Size int64  `json:"size"` | ||||||
|  | 	SHA  string `json:"sha"` | ||||||
|  | 	URL  string `json:"url"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GitTreeResponse returns a git tree | ||||||
|  | type GitTreeResponse struct { | ||||||
|  | 	SHA       string     `json:"sha"` | ||||||
|  | 	URL       string     `json:"url"` | ||||||
|  | 	Entries   []GitEntry `json:"tree"` | ||||||
|  | 	Truncated bool       `json:"truncated"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetTrees downloads a file of repository, ref can be branch/tag/commit. | ||||||
|  | // e.g.: ref -> master, tree -> macaron.go(no leading slash) | ||||||
|  | func (c *Client) GetTrees(user, repo, ref string, recursive bool) (*GitTreeResponse, error) { | ||||||
|  | 	var trees GitTreeResponse | ||||||
|  | 	var path = fmt.Sprintf("/repos/%s/%s/git/trees/%s", user, repo, ref) | ||||||
|  | 	if recursive { | ||||||
|  | 		path += "?recursive=1" | ||||||
|  | 	} | ||||||
|  | 	err := c.getParsedResponse("GET", path, nil, nil, &trees) | ||||||
|  | 	return &trees, err | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user