diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 8a4d69e8f25..86ed1ba5a6b 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1484,7 +1484,11 @@ func Routes() *web.Router { Post(reqToken(), reqRepoWriter(unit.TypeCode), bind(api.CreateStatusOption{}), repo.NewCommitStatus) }, reqRepoReader(unit.TypeCode)) m.Group("/commits", func() { - m.Get("", context.ReferencesGitRepo(), repo.GetAllCommits) + m.Group("", func() { + m.Get("", repo.GetAllCommits) + m.Get("/{sha}", repo.GetSingleCommit) // GitHub-compatible endpoint + m.Get("/{sha}.{diffType:diff|patch}", repo.DownloadCommitDiffOrPatch) + }, context.ReferencesGitRepo(true)) m.PathGroup("/*", func(g *web.RouterPathGroup) { // Mis-configured reverse proxy might decode the `%2F` to slash ahead, so we need to support both formats (escaped, unescaped) here. // It also matches GitHub's behavior diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index e4c2a0df4b7..25effda94f1 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -24,7 +24,7 @@ import ( func GetSingleCommit(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/git/commits/{sha} repository repoGetSingleCommit // --- - // summary: Get a single commit from a repository + // summary: Get a single commit from a repository, it has a GitHub-compatible alias "/repos/{owner}/{repo}/commits/{ref}" // produces: // - application/json // parameters: diff --git a/templates/swagger/v1-openapi3.generated.json b/templates/swagger/v1-openapi3.generated.json index 031576ebd34..27f366e91a5 100644 --- a/templates/swagger/v1-openapi3.generated.json +++ b/templates/swagger/v1-openapi3.generated.json @@ -20470,7 +20470,7 @@ "$ref": "#/components/responses/validationError" } }, - "summary": "Get a single commit from a repository", + "summary": "Get a single commit from a repository, it has a GitHub-compatible alias \"/repos/{owner}/{repo}/commits/{ref}\"", "tags": [ "repository" ] diff --git a/templates/swagger/v1-swagger.generated.json b/templates/swagger/v1-swagger.generated.json index ee72660568a..38dfac5d6ff 100644 --- a/templates/swagger/v1-swagger.generated.json +++ b/templates/swagger/v1-swagger.generated.json @@ -9067,7 +9067,7 @@ "tags": [ "repository" ], - "summary": "Get a single commit from a repository", + "summary": "Get a single commit from a repository, it has a GitHub-compatible alias \"/repos/{owner}/{repo}/commits/{ref}\"", "operationId": "repoGetSingleCommit", "parameters": [ { diff --git a/tests/integration/api_repo_git_commits_test.go b/tests/integration/api_repo_git_commits_test.go index d7542b38f50..7905e6acb1e 100644 --- a/tests/integration/api_repo_git_commits_test.go +++ b/tests/integration/api_repo_git_commits_test.go @@ -26,22 +26,15 @@ func compareCommitFiles(t *testing.T, expect []string, files []*api.CommitAffect func TestAPIReposGitCommits(t *testing.T) { defer tests.PrepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - // Login as User2. - session := loginUser(t, user.Name) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + session := loginUser(t, user2.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // check invalid requests - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/12345", user.Name). - AddTokenAuth(token) - MakeRequest(t, req, http.StatusNotFound) - - req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/..", user.Name). - AddTokenAuth(token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/..", user2.Name).AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) - req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/branch-not-exist", user.Name). - AddTokenAuth(token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/ref-not-exist", user2.Name).AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) for _, ref := range [...]string{ @@ -50,8 +43,10 @@ func TestAPIReposGitCommits(t *testing.T) { "65f1", // short sha "65f1bf27bc3bf70f64657658635e66094edbcb4d", // full sha } { - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/%s", user.Name, ref). - AddTokenAuth(token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/%s", user2.Name, ref).AddTokenAuth(token) + MakeRequest(t, req, http.StatusOK) + // GitHub-compatible + req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/commits/%s", user2.Name, ref).AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) } }