mirror of
https://github.com/hanzoai/forge.git
synced 2026-10-30 15:00:39 +00:00
Source files keep their SPDX-License-Identifier and Hanzo copyright line; the Gitea, Gogs and LFS Test Server copyrights they used to repeat now live once in NOTICE, alongside LICENSE. The header lint accepts any copyright line above the SPDX line, so it no longer demands an upstream one. Co-authored-by: Hanzo Dev <[email protected]>
132 lines
3.7 KiB
Go
132 lines
3.7 KiB
Go
// Copyright 2026 Hanzo AI, Inc. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package repo
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
user_model "github.com/hanzoai/git/models/user"
|
|
"github.com/hanzoai/git/modules/gitrepo"
|
|
api "github.com/hanzoai/git/modules/structs"
|
|
"github.com/hanzoai/git/services/context"
|
|
"github.com/hanzoai/git/services/convert"
|
|
git_service "github.com/hanzoai/git/services/git"
|
|
)
|
|
|
|
// CompareDiff compare two branches or commits
|
|
func CompareDiff(ctx *context.APIContext) {
|
|
// swagger:operation GET /repos/{owner}/{repo}/compare/{basehead} repository repoCompareDiff
|
|
// ---
|
|
// summary: Get commit comparison information
|
|
// description: |
|
|
// By default returns JSON commit comparison information. The raw diff or patch can be
|
|
// requested with the `output` query parameter set to `diff` or `patch` respectively.
|
|
// produces:
|
|
// - application/json
|
|
// - text/plain
|
|
// parameters:
|
|
// - name: owner
|
|
// in: path
|
|
// description: owner of the repo
|
|
// type: string
|
|
// required: true
|
|
// - name: repo
|
|
// in: path
|
|
// description: name of the repo
|
|
// type: string
|
|
// required: true
|
|
// - name: basehead
|
|
// in: path
|
|
// description: compare two refs as `base...head` (or `base..head`); refs may be branches, tags, full or short SHAs (including branch names that contain slashes), optionally with a `^` or `~N` revision suffix.
|
|
// type: string
|
|
// required: true
|
|
// - name: output
|
|
// in: query
|
|
// description: return the raw comparison as `diff` or `patch` instead of JSON
|
|
// type: string
|
|
// enum:
|
|
// - diff
|
|
// - patch
|
|
// responses:
|
|
// "200":
|
|
// "$ref": "#/responses/Compare"
|
|
// "400":
|
|
// "$ref": "#/responses/error"
|
|
// "404":
|
|
// "$ref": "#/responses/notFound"
|
|
|
|
if ctx.Repo.GitRepo == nil {
|
|
var err error
|
|
ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository)
|
|
if err != nil {
|
|
ctx.APIErrorInternal(err)
|
|
return
|
|
}
|
|
}
|
|
|
|
compareInfo, closer := parseCompareInfo(ctx, ctx.PathParam("*"))
|
|
if ctx.Written() {
|
|
return
|
|
}
|
|
defer closer()
|
|
|
|
// ?output=diff|patch returns the raw output, otherwise the JSON comparison is returned.
|
|
switch ctx.FormString("output") {
|
|
case "diff":
|
|
downloadCompareDiffOrPatch(ctx, compareInfo, false)
|
|
return
|
|
case "patch":
|
|
downloadCompareDiffOrPatch(ctx, compareInfo, true)
|
|
return
|
|
}
|
|
|
|
verification := ctx.FormString("verification") == "" || ctx.FormBool("verification")
|
|
files := ctx.FormString("files") == "" || ctx.FormBool("files")
|
|
|
|
apiCommits := make([]*api.Commit, 0, len(compareInfo.Commits))
|
|
userCache := make(map[string]*user_model.User)
|
|
|
|
for i := 0; i < len(compareInfo.Commits); i++ {
|
|
apiCommit, err := convert.ToCommit(
|
|
ctx,
|
|
compareInfo.HeadRepo,
|
|
compareInfo.HeadGitRepo,
|
|
compareInfo.Commits[i],
|
|
userCache,
|
|
convert.ToCommitOptions{
|
|
Stat: true,
|
|
Verification: verification,
|
|
Files: files,
|
|
},
|
|
)
|
|
if err != nil {
|
|
ctx.APIErrorInternal(err)
|
|
return
|
|
}
|
|
apiCommits = append(apiCommits, apiCommit)
|
|
}
|
|
|
|
ctx.JSON(http.StatusOK, &api.Compare{
|
|
TotalCommits: len(compareInfo.Commits),
|
|
Commits: apiCommits,
|
|
})
|
|
}
|
|
|
|
// downloadCompareDiffOrPatch writes a comparison's raw diff or patch to the response.
|
|
func downloadCompareDiffOrPatch(ctx *context.APIContext, compareInfo *git_service.CompareInfo, patch bool) {
|
|
ctx.Resp.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
|
compareArg := compareInfo.BaseCommitID + compareInfo.CompareSeparator + compareInfo.HeadCommitID
|
|
|
|
var err error
|
|
if patch {
|
|
err = compareInfo.HeadGitRepo.GetPatch(compareArg, ctx.Resp)
|
|
} else {
|
|
err = compareInfo.HeadGitRepo.GetDiff(compareArg, ctx.Resp)
|
|
}
|
|
if err != nil {
|
|
ctx.APIErrorInternal(err)
|
|
return
|
|
}
|
|
}
|