Merge branch 'rs-revert-api' into 'master'
Add revert to commits API Closes gitlab-org/release/framework#48 See merge request gitlab-org/gitlab-ce!22919
This commit is contained in:
commit
8d74ef331c
5 changed files with 199 additions and 2 deletions
|
@ -24,8 +24,12 @@ module Commits
|
|||
start_project: @start_project,
|
||||
start_branch_name: @start_branch)
|
||||
rescue Gitlab::Git::Repository::CreateTreeError
|
||||
error_msg = "Sorry, we cannot #{action.to_s.dasherize} this #{@commit.change_type_title(current_user)} automatically.
|
||||
This #{@commit.change_type_title(current_user)} may already have been #{action.to_s.dasherize}ed, or a more recent commit may have updated some of its content."
|
||||
act = action.to_s.dasherize
|
||||
type = @commit.change_type_title(current_user)
|
||||
|
||||
error_msg = "Sorry, we cannot #{act} this #{type} automatically. " \
|
||||
"This #{type} may already have been #{act}ed, or a more recent " \
|
||||
"commit may have updated some of its content."
|
||||
raise ChangeError, error_msg
|
||||
end
|
||||
end
|
||||
|
|
5
changelogs/unreleased/rs-revert-api.yml
Normal file
5
changelogs/unreleased/rs-revert-api.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add revert to commits API
|
||||
merge_request: 22919
|
||||
author:
|
||||
type: added
|
|
@ -288,6 +288,47 @@ Example response:
|
|||
}
|
||||
```
|
||||
|
||||
## Revert a commit
|
||||
|
||||
> [Introduced][ce-22919] in GitLab 11.6.
|
||||
|
||||
Reverts a commit in a given branch.
|
||||
|
||||
```
|
||||
POST /projects/:id/repository/commits/:sha/revert
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
|
||||
| `sha` | string | yes | Commit SHA to revert |
|
||||
| `branch` | string | yes | Target branch name |
|
||||
|
||||
```bash
|
||||
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" --form "branch=master" "https://gitlab.example.com/api/v4/projects/5/repository/commits/a738f717824ff53aebad8b090c1b79a14f2bd9e8/revert"
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"id":"8b090c1b79a14f2bd9e8a738f717824ff53aebad",
|
||||
"short_id": "8b090c1b",
|
||||
"title":"Revert \"Feature added\"",
|
||||
"created_at":"2018-11-08T15:55:26.000Z",
|
||||
"parent_ids":["a738f717824ff53aebad8b090c1b79a14f2bd9e8"],
|
||||
"message":"Revert \"Feature added\"\n\nThis reverts commit a738f717824ff53aebad8b090c1b79a14f2bd9e8",
|
||||
"author_name":"Administrator",
|
||||
"author_email":"admin@example.com",
|
||||
"authored_date":"2018-11-08T15:55:26.000Z",
|
||||
"committer_name":"Administrator",
|
||||
"committer_email":"admin@example.com",
|
||||
"committed_date":"2018-11-08T15:55:26.000Z"
|
||||
}
|
||||
```
|
||||
|
||||
## Get the diff of a commit
|
||||
|
||||
Get the diff of a commit in a project.
|
||||
|
@ -619,3 +660,4 @@ Example response:
|
|||
[ce-8047]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8047
|
||||
[ce-15026]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/15026
|
||||
[ce-18004]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/18004
|
||||
[ce-22919]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/22919
|
||||
|
|
|
@ -204,6 +204,40 @@ module API
|
|||
end
|
||||
end
|
||||
|
||||
desc 'Revert a commit in a branch' do
|
||||
detail 'This feature was introduced in GitLab 11.6'
|
||||
success Entities::Commit
|
||||
end
|
||||
params do
|
||||
requires :sha, type: String, desc: 'Commit SHA to revert'
|
||||
requires :branch, type: String, desc: 'Target branch name', allow_blank: false
|
||||
end
|
||||
post ':id/repository/commits/:sha/revert', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
|
||||
authorize_push_to_branch!(params[:branch])
|
||||
|
||||
commit = user_project.commit(params[:sha])
|
||||
not_found!('Commit') unless commit
|
||||
|
||||
find_branch!(params[:branch])
|
||||
|
||||
commit_params = {
|
||||
commit: commit,
|
||||
start_branch: params[:branch],
|
||||
branch_name: params[:branch]
|
||||
}
|
||||
|
||||
result = ::Commits::RevertService
|
||||
.new(user_project, current_user, commit_params)
|
||||
.execute
|
||||
|
||||
if result[:status] == :success
|
||||
present user_project.repository.commit(result[:result]),
|
||||
with: Entities::Commit
|
||||
else
|
||||
render_api_error!(result[:message], 400)
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Get all references a commit is pushed to' do
|
||||
detail 'This feature was introduced in GitLab 10.6'
|
||||
success Entities::BasicRef
|
||||
|
|
|
@ -1208,6 +1208,118 @@ describe API::Commits do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'POST :id/repository/commits/:sha/revert' do
|
||||
let(:commit_id) { 'b83d6e391c22777fca1ed3012fce84f633d7fed0' }
|
||||
let(:commit) { project.commit(commit_id) }
|
||||
let(:branch) { 'master' }
|
||||
let(:route) { "/projects/#{project_id}/repository/commits/#{commit_id}/revert" }
|
||||
|
||||
shared_examples_for 'ref revert' do
|
||||
context 'when ref exists' do
|
||||
it 'reverts the ref commit' do
|
||||
post api(route, current_user), branch: branch
|
||||
|
||||
expect(response).to have_gitlab_http_status(201)
|
||||
expect(response).to match_response_schema('public_api/v4/commit/basic')
|
||||
|
||||
expect(json_response['message']).to eq(commit.revert_message(user))
|
||||
expect(json_response['author_name']).to eq(user.name)
|
||||
expect(json_response['committer_name']).to eq(user.name)
|
||||
expect(json_response['parent_ids']).to contain_exactly(commit_id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when repository is disabled' do
|
||||
include_context 'disabled repository'
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { post api(route, current_user), branch: branch }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when unauthenticated', 'and project is public' do
|
||||
let(:project) { create(:project, :public, :repository) }
|
||||
|
||||
it_behaves_like '403 response' do
|
||||
let(:request) { post api(route), branch: branch }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when unauthenticated', 'and project is private' do
|
||||
it_behaves_like '404 response' do
|
||||
let(:request) { post api(route), branch: branch }
|
||||
let(:message) { '404 Project Not Found' }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when authenticated', 'as an owner' do
|
||||
let(:current_user) { user }
|
||||
|
||||
it_behaves_like 'ref revert'
|
||||
|
||||
context 'when ref does not exist' do
|
||||
let(:commit_id) { 'unknown' }
|
||||
|
||||
it_behaves_like '404 response' do
|
||||
let(:request) { post api(route, current_user), branch: branch }
|
||||
let(:message) { '404 Commit Not Found' }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when branch is missing' do
|
||||
it_behaves_like '400 response' do
|
||||
let(:request) { post api(route, current_user) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when branch is empty' do
|
||||
['', ' '].each do |branch|
|
||||
it_behaves_like '400 response' do
|
||||
let(:request) { post api(route, current_user), branch: branch }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when branch does not exist' do
|
||||
it_behaves_like '404 response' do
|
||||
let(:request) { post api(route, current_user), branch: 'foo' }
|
||||
let(:message) { '404 Branch Not Found' }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when ref contains a dot' do
|
||||
let(:commit_id) { branch_with_dot.name }
|
||||
let(:commit) { project.repository.commit(commit_id) }
|
||||
|
||||
it_behaves_like '400 response' do
|
||||
let(:request) { post api(route, current_user) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when authenticated', 'as a developer' do
|
||||
let(:current_user) { user }
|
||||
|
||||
before do
|
||||
project.add_developer(user)
|
||||
end
|
||||
|
||||
context 'when branch is protected' do
|
||||
before do
|
||||
create(:protected_branch, project: project, name: 'feature')
|
||||
end
|
||||
|
||||
it 'returns 400 if you are not allowed to push to the target branch' do
|
||||
post api(route, current_user), branch: 'feature'
|
||||
|
||||
expect(response).to have_gitlab_http_status(:forbidden)
|
||||
expect(json_response['message']).to match(/You are not allowed to push into this branch/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /projects/:id/repository/commits/:sha/comments' do
|
||||
let(:commit) { project.repository.commit }
|
||||
let(:commit_id) { commit.id }
|
||||
|
|
Loading…
Reference in a new issue