Skip to content
Snippets Groups Projects
commits.rb 3.84 KiB
Newer Older
  • Learn to ignore specific revisions
  • require 'mime/types'
    
    module API
    
      # Projects commits API
    
      class Commits < Grape::API
        before { authenticate! }
        before { authorize! :download_code, user_project }
    
        resource :projects do
          # Get a project repository commits
          #
          # Parameters:
          #   id (required) - The ID of a project
          #   ref_name (optional) - The name of a repository branch or tag, if not given the default branch is used
          # Example Request:
          #   GET /projects/:id/repository/commits
          get ":id/repository/commits" do
            page = (params[:page] || 0).to_i
            per_page = (params[:per_page] || 20).to_i
            ref = params[:ref_name] || user_project.try(:default_branch) || 'master'
    
            commits = user_project.repository.commits(ref, nil, per_page, page * per_page)
            present commits, with: Entities::RepoCommit
          end
    
          # Get a specific commit of a project
          #
          # Parameters:
          #   id (required) - The ID of a project
          #   sha (required) - The commit hash or name of a repository branch or tag
          # Example Request:
          #   GET /projects/:id/repository/commits/:sha
          get ":id/repository/commits/:sha" do
            sha = params[:sha]
    
            commit = user_project.commit(sha)
    
            not_found! "Commit" unless commit
            present commit, with: Entities::RepoCommitDetail
          end
    
          # Get the diff for a specific commit of a project
          #
          # Parameters:
          #   id (required) - The ID of a project
          #   sha (required) - The commit or branch name
          # Example Request:
          #   GET /projects/:id/repository/commits/:sha/diff
          get ":id/repository/commits/:sha/diff" do
            sha = params[:sha]
    
            commit = user_project.commit(sha)
    
            not_found! "Commit" unless commit
            commit.diffs
          end
    
    
          # Get a commit's comments
          #
          # Parameters:
          #   id (required) - The ID of a project
          #   sha (required) - The commit hash
          # Examples:
          #   GET /projects/:id/repository/commits/:sha/comments
          get ':id/repository/commits/:sha/comments' do
            sha = params[:sha]
    
            commit = user_project.commit(sha)
    
            not_found! 'Commit' unless commit
    
            notes = Note.where(commit_id: commit.id).order(:created_at)
    
            present paginate(notes), with: Entities::CommitNote
          end
    
          # Post comment to commit
          #
          # Parameters:
          #   id (required) - The ID of a project
          #   sha (required) - The commit hash
          #   note (required) - Text of comment
          #   path (optional) - The file path
          #   line (optional) - The line number
          #   line_type (optional) - The type of line (new or old)
          # Examples:
          #   POST /projects/:id/repository/commits/:sha/comments
          post ':id/repository/commits/:sha/comments' do
            required_attributes! [:note]
    
            sha = params[:sha]
    
            commit = user_project.commit(sha)
    
            not_found! 'Commit' unless commit
            opts = {
              note: params[:note],
              noteable_type: 'Commit',
              commit_id: commit.id
            }
    
            if params[:path] && params[:line] && params[:line_type]
              commit.diffs.each do |diff|
                next unless diff.new_path == params[:path]
                lines = Gitlab::Diff::Parser.new.parse(diff.diff.lines.to_a)
    
                lines.each do |line|
                  next unless line.new_pos == params[:line].to_i && 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
            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)