4587c78afa
* upstream/master: (1122 commits) Update CHANGELOG.md for 8.16.2 Display project ID in project settings (!8572) fixed points from comments to improve code quality Update CHANGELOG.md for 8.14.8 Statisfy eslint Add CHANGELOG entry Fix access to the wiki code via HTTP when repository feature disabled Display fullscreen button on small screens (!5302) Prevent removing fields from dropdowns on input elements fix for all themes Return struct instead of multiple values Fix race conditions for AuthorizedProjectsWorker Add User#nested_groups and User#nested_projects methods Fix spec failure due to timestamp ordering issue in mySQL Fixed error with filter keyboard tests `can?` already includes the `feature_available?` check Test there is no Merge Request button when MRs are disabled Ensure the correct Merge Request button is found Add 409 conflict tests Add CHANGELOG ...
203 lines
7.4 KiB
Ruby
203 lines
7.4 KiB
Ruby
require 'mime/types'
|
|
|
|
module API
|
|
class Commits < Grape::API
|
|
include PaginationParams
|
|
|
|
before { authenticate! }
|
|
before { authorize! :download_code, user_project }
|
|
|
|
params do
|
|
requires :id, type: String, desc: 'The ID of a project'
|
|
end
|
|
resource :projects do
|
|
desc 'Get a project repository commits' do
|
|
success Entities::RepoCommit
|
|
end
|
|
params do
|
|
optional :ref_name, type: String, desc: 'The name of a repository branch or tag, if not given the default branch is used'
|
|
optional :since, type: String, desc: 'Only commits after or in this date will be returned'
|
|
optional :until, type: String, desc: 'Only commits before or in this date will be returned'
|
|
optional :page, type: Integer, default: 0, desc: 'The page for pagination'
|
|
optional :per_page, type: Integer, default: 20, desc: 'The number of results per page'
|
|
optional :path, type: String, desc: 'The file path'
|
|
end
|
|
get ":id/repository/commits" do
|
|
# TODO remove the next line for 9.0, use DateTime type in the params block
|
|
datetime_attributes! :since, :until
|
|
|
|
ref = params[:ref_name] || user_project.try(:default_branch) || 'master'
|
|
offset = params[:page] * params[:per_page]
|
|
|
|
commits = user_project.repository.commits(ref,
|
|
path: params[:path],
|
|
limit: params[:per_page],
|
|
offset: offset,
|
|
after: params[:since],
|
|
before: params[:until])
|
|
|
|
present commits, with: Entities::RepoCommit
|
|
end
|
|
|
|
desc 'Commit multiple file changes as one commit' do
|
|
success Entities::RepoCommitDetail
|
|
detail 'This feature was introduced in GitLab 8.13'
|
|
end
|
|
params do
|
|
requires :branch_name, type: String, desc: 'The name of branch'
|
|
requires :commit_message, type: String, desc: 'Commit message'
|
|
requires :actions, type: Array[Hash], desc: 'Actions to perform in commit'
|
|
optional :author_email, type: String, desc: 'Author email for commit'
|
|
optional :author_name, type: String, desc: 'Author name for commit'
|
|
end
|
|
post ":id/repository/commits" do
|
|
authorize! :push_code, user_project
|
|
|
|
attrs = declared_params
|
|
attrs[:start_branch] = attrs[:branch_name]
|
|
attrs[:target_branch] = attrs[:branch_name]
|
|
attrs[:actions].map! do |action|
|
|
action[:action] = action[:action].to_sym
|
|
action[:file_path].slice!(0) if action[:file_path] && action[:file_path].start_with?('/')
|
|
action[:previous_path].slice!(0) if action[:previous_path] && action[:previous_path].start_with?('/')
|
|
action
|
|
end
|
|
|
|
result = ::Files::MultiService.new(user_project, current_user, attrs).execute
|
|
|
|
if result[:status] == :success
|
|
commit_detail = user_project.repository.commits(result[:result], limit: 1).first
|
|
present commit_detail, with: Entities::RepoCommitDetail
|
|
else
|
|
render_api_error!(result[:message], 400)
|
|
end
|
|
end
|
|
|
|
desc 'Get a specific commit of a project' do
|
|
success Entities::RepoCommitDetail
|
|
failure [[404, 'Not Found']]
|
|
end
|
|
params do
|
|
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
|
|
end
|
|
get ":id/repository/commits/:sha" do
|
|
commit = user_project.commit(params[:sha])
|
|
|
|
not_found! "Commit" unless commit
|
|
|
|
present commit, with: Entities::RepoCommitDetail
|
|
end
|
|
|
|
desc 'Get the diff for a specific commit of a project' do
|
|
failure [[404, 'Not Found']]
|
|
end
|
|
params do
|
|
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
|
|
end
|
|
get ":id/repository/commits/:sha/diff" do
|
|
commit = user_project.commit(params[:sha])
|
|
|
|
not_found! "Commit" unless commit
|
|
|
|
commit.raw_diffs.to_a
|
|
end
|
|
|
|
desc "Get a commit's comments" do
|
|
success Entities::CommitNote
|
|
failure [[404, 'Not Found']]
|
|
end
|
|
params do
|
|
use :pagination
|
|
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
|
|
end
|
|
get ':id/repository/commits/:sha/comments' do
|
|
commit = user_project.commit(params[:sha])
|
|
|
|
not_found! 'Commit' unless commit
|
|
notes = Note.where(commit_id: commit.id).order(:created_at)
|
|
|
|
present paginate(notes), with: Entities::CommitNote
|
|
end
|
|
|
|
desc 'Cherry pick commit into a branch' do
|
|
detail 'This feature was introduced in GitLab 8.15'
|
|
success Entities::RepoCommit
|
|
end
|
|
params do
|
|
requires :sha, type: String, desc: 'A commit sha to be cherry picked'
|
|
requires :branch, type: String, desc: 'The name of the branch'
|
|
end
|
|
post ':id/repository/commits/:sha/cherry_pick' do
|
|
authorize! :push_code, user_project
|
|
|
|
commit = user_project.commit(params[:sha])
|
|
not_found!('Commit') unless commit
|
|
|
|
branch = user_project.repository.find_branch(params[:branch])
|
|
not_found!('Branch') unless branch
|
|
|
|
commit_params = {
|
|
commit: commit,
|
|
create_merge_request: false,
|
|
target_branch: params[:branch]
|
|
}
|
|
|
|
result = ::Commits::CherryPickService.new(user_project, current_user, commit_params).execute
|
|
|
|
if result[:status] == :success
|
|
branch = user_project.repository.find_branch(params[:branch])
|
|
present user_project.repository.commit(branch.dereferenced_target), with: Entities::RepoCommit
|
|
else
|
|
render_api_error!(result[:message], 400)
|
|
end
|
|
end
|
|
|
|
desc 'Post comment to commit' do
|
|
success Entities::CommitNote
|
|
end
|
|
params do
|
|
requires :sha, type: String, regexp: /\A\h{6,40}\z/, desc: "The commit's SHA"
|
|
requires :note, type: String, desc: 'The text of the comment'
|
|
optional :path, type: String, desc: 'The file path'
|
|
given :path do
|
|
requires :line, type: Integer, desc: 'The line number'
|
|
requires :line_type, type: String, values: ['new', 'old'], default: 'new', desc: 'The type of the line'
|
|
end
|
|
end
|
|
post ':id/repository/commits/:sha/comments' do
|
|
commit = user_project.commit(params[:sha])
|
|
not_found! 'Commit' unless commit
|
|
|
|
opts = {
|
|
note: params[:note],
|
|
noteable_type: 'Commit',
|
|
commit_id: commit.id
|
|
}
|
|
|
|
if params[:path]
|
|
commit.raw_diffs(all_diffs: true).each do |diff|
|
|
next unless diff.new_path == params[:path]
|
|
lines = Gitlab::Diff::Parser.new.parse(diff.diff.each_line)
|
|
|
|
lines.each do |line|
|
|
next unless line.new_pos == params[:line] && line.type == params[:line_type]
|
|
break opts[:line_code] = Gitlab::Diff::LineCode.generate(diff.new_path, line.new_pos, line.old_pos)
|
|
end
|
|
|
|
break if opts[:line_code]
|
|
end
|
|
|
|
opts[:type] = LegacyDiffNote.name if opts[:line_code]
|
|
end
|
|
|
|
note = ::Notes::CreateService.new(user_project, current_user, opts).execute
|
|
|
|
if note.save
|
|
present note, with: Entities::CommitNote
|
|
else
|
|
render_api_error!("Failed to save note #{note.errors.messages}", 400)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|