Skip to content

Commit 7544034

Browse files
committed
feat: implement branch/commit comparison API
- Add a new API endpoint for comparing differences between branches or commits - Implement a new function `CompareDiff` in the `repo` package to handle the comparison logic - Create a new file `compare.go` in the `common` package to parse and process comparison information - Define a new `CompareInfo` struct to hold comparison details - Add logic to determine the base and head repositories for comparison, including handling of forks and permission checks - Implement comparison logic to fetch and compare information between branches or commits, including support for file-only comparisons Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
1 parent bbe5cd7 commit 7544034

File tree

3 files changed

+397
-0
lines changed

3 files changed

+397
-0
lines changed

routers/api/v1/api.go

+2
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,8 @@ func Routes() *web.Route {
10661066
m.Post("/migrate", reqToken(), bind(api.MigrateRepoOptions{}), repo.Migrate)
10671067

10681068
m.Group("/{username}/{reponame}", func() {
1069+
m.Get("/compare/*", repo.CompareDiff)
1070+
10691071
m.Combo("").Get(reqAnyRepoReader(), repo.Get).
10701072
Delete(reqToken(), reqOwner(), repo.Delete).
10711073
Patch(reqToken(), reqAdmin(), bind(api.EditRepoOption{}), repo.Edit)

routers/api/v1/repo/compare.go

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package repo
5+
6+
import (
7+
"net/http"
8+
9+
user_model "code.gitea.io/gitea/models/user"
10+
"code.gitea.io/gitea/modules/gitrepo"
11+
api "code.gitea.io/gitea/modules/structs"
12+
"code.gitea.io/gitea/routers/common"
13+
"code.gitea.io/gitea/services/context"
14+
"code.gitea.io/gitea/services/convert"
15+
)
16+
17+
// CompareDiff compare two branches or commits
18+
func CompareDiff(ctx *context.APIContext) {
19+
// swagger:operation GET /repos/{owner}/{repo}/compare/{diff} Get compared branches information
20+
// ---
21+
// summary: Get compared branches information
22+
// produces:
23+
// - application/json
24+
// parameters:
25+
// - name: owner
26+
// in: path
27+
// description: owner of the repo
28+
// type: string
29+
// required: true
30+
// - name: repo
31+
// in: path
32+
// description: name of the repo
33+
// type: string
34+
// required: true
35+
// - name: diff
36+
// in: path
37+
// description: compare two branches or commits
38+
// type: string
39+
// required: true
40+
// responses:
41+
// "200":
42+
// "$ref": "#/responses/Repository"
43+
// "404":
44+
// "$ref": "#/responses/notFound"
45+
46+
if ctx.Repo.GitRepo == nil {
47+
gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
48+
if err != nil {
49+
ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
50+
return
51+
}
52+
ctx.Repo.GitRepo = gitRepo
53+
defer gitRepo.Close()
54+
}
55+
56+
ci := common.ParseCompareInfo(ctx)
57+
defer func() {
58+
if ci != nil && ci.HeadGitRepo != nil {
59+
ci.HeadGitRepo.Close()
60+
}
61+
}()
62+
if ctx.Written() {
63+
return
64+
}
65+
66+
apiCommits := make([]*api.Commit, 0, len(ci.CompareInfo.Commits))
67+
userCache := make(map[string]*user_model.User)
68+
for i := 0; i < len(ci.CompareInfo.Commits); i++ {
69+
apiCommit, err := convert.ToCommit(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, ci.CompareInfo.Commits[i], userCache,
70+
convert.ToCommitOptions{
71+
Stat: true,
72+
Verification: ctx.FormBool("verification"),
73+
Files: ctx.FormBool("files"),
74+
})
75+
if err != nil {
76+
ctx.ServerError("toCommit", err)
77+
return
78+
}
79+
apiCommits = append(apiCommits, apiCommit)
80+
}
81+
82+
ctx.JSON(http.StatusOK, &apiCommits)
83+
}

0 commit comments

Comments
 (0)