mirror of
https://github.com/go-gitea/gitea.git
synced 2026-04-14 05:29:56 +09:00
Backport #37185 by @Mohit25022005 Fix 500 error when comparing branches across fork repositories ## Problem The compare API returns a 500 Internal Server Error when comparing branches where the head commit exists only in the fork repository. ## Cause The API was using the base repository's GitRepo and repository context when converting commits. This fails when the commit does not exist in the base repository, resulting in a "fatal: bad object" error. ## Solution Use the head repository and HeadGitRepo when available to ensure commits are resolved in the correct repository context. ## Result * Fixes "fatal: bad object" error * Enables proper comparison between base and fork repositories * Prevents 500 Internal Server Error Fixes #37168 Co-authored-by: Mohit Swarnkar <mohitswarnkar13@gmail.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -62,13 +62,20 @@ func CompareDiff(ctx *context.APIContext) {
|
||||
|
||||
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, ctx.Repo.Repository, ctx.Repo.GitRepo, compareInfo.Commits[i], userCache,
|
||||
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
|
||||
|
||||
@@ -5,46 +5,60 @@ package integration
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/tests"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAPICompareBranches(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
onGiteaRun(t, func(t *testing.T, _ *url.URL) {
|
||||
session2 := loginUser(t, "user2")
|
||||
token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeWriteRepository)
|
||||
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
// Login as User2.
|
||||
session := loginUser(t, user.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
||||
t.Run("CompareBranches", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
t.Run("CompareBranches", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo20/compare/add-csv...remove-files-b").AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo20/compare/add-csv...remove-files-b").AddTokenAuth(token2)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
apiResp := DecodeJSON(t, resp, &api.Compare{})
|
||||
assert.Equal(t, 2, apiResp.TotalCommits)
|
||||
assert.Len(t, apiResp.Commits, 2)
|
||||
})
|
||||
|
||||
var apiResp *api.Compare
|
||||
DecodeJSON(t, resp, &apiResp)
|
||||
t.Run("CompareCommits", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
assert.Equal(t, 2, apiResp.TotalCommits)
|
||||
assert.Len(t, apiResp.Commits, 2)
|
||||
})
|
||||
req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo20/compare/808038d2f71b0ab02099...c8e31bc7688741a5287f").AddTokenAuth(token2)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
apiResp := DecodeJSON(t, resp, &api.Compare{})
|
||||
assert.Equal(t, 1, apiResp.TotalCommits)
|
||||
assert.Len(t, apiResp.Commits, 1)
|
||||
})
|
||||
|
||||
t.Run("CompareCommits", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo20/compare/808038d2f71b0ab02099...c8e31bc7688741a5287f").AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
t.Run("CompareForkOnlyCommit", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
var apiResp *api.Compare
|
||||
DecodeJSON(t, resp, &apiResp)
|
||||
user13 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 13})
|
||||
repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11})
|
||||
user13Sess := loginUser(t, "user13")
|
||||
user13Token := getTokenForLoggedInUser(t, user13Sess, auth_model.AccessTokenScopeWriteRepository)
|
||||
|
||||
assert.Equal(t, 1, apiResp.TotalCommits)
|
||||
assert.Len(t, apiResp.Commits, 1)
|
||||
_, err := createFileInBranch(user13, repo11, createFileInBranchOptions{OldBranch: "master", NewBranch: "new-branch"}, map[string]string{"file.txt": "content"})
|
||||
require.NoError(t, err)
|
||||
req := NewRequestf(t, "GET", "/api/v1/repos/user12/repo10/compare/master...user13:new-branch").AddTokenAuth(user13Token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
apiResp := DecodeJSON(t, resp, &api.Compare{})
|
||||
assert.Equal(t, 1, apiResp.TotalCommits)
|
||||
assert.Len(t, apiResp.Commits, 1)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user