mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-13 08:41:03 +00:00
feat: add raw diff/patch endpoint for repository comparisons (#37632)
## Summary
Adds `GET
/repos/{owner}/{repo}/compare/{basehead}.{diffType:diff|patch}`,
mirroring the existing `/git/commits/{sha}.{diffType}` endpoint but for
comparisons between two arbitrary refs.
The new endpoint streams a raw unified diff or `git format-patch` output
between any two refs:
GET /repos/{owner}/{repo}/compare/main...feature.diff
GET /repos/{owner}/{repo}/compare/v1.0..v1.1.patch
GET /repos/{owner}/{repo}/compare/abc1234...def5678.diff
Resolves #5561, #13416 and #17165.
AI was used while creating this PR. Automated tests were added as per
the contribution policy.
---------
Co-authored-by: bircni <bircni@icloud.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
api "gitea.dev/modules/structs"
|
||||
"gitea.dev/services/context"
|
||||
"gitea.dev/services/convert"
|
||||
git_service "gitea.dev/services/git"
|
||||
)
|
||||
|
||||
// CompareDiff compare two branches or commits
|
||||
@@ -18,8 +19,12 @@ 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
|
||||
@@ -33,9 +38,16 @@ func CompareDiff(ctx *context.APIContext) {
|
||||
// required: true
|
||||
// - name: basehead
|
||||
// in: path
|
||||
// description: compare two branches or commits
|
||||
// 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.
|
||||
// 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"
|
||||
@@ -57,6 +69,16 @@ func CompareDiff(ctx *context.APIContext) {
|
||||
}
|
||||
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")
|
||||
|
||||
@@ -88,3 +110,20 @@ func CompareDiff(ctx *context.APIContext) {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user