Commit b0f300063e499f398c6e563b1b3960fbb104d16a

Authored by Dmitriy Zaporozhets
2 parents 8841eec4 bd20ec1a

Merge branch 'feature/delete_file' of /home/git/repositories/gitlab/gitlabhq

app/contexts/files/delete_context.rb 0 → 100644
... ... @@ -0,0 +1,38 @@
  1 +module Files
  2 + class DeleteContext < BaseContext
  3 + def execute
  4 + allowed = if project.protected_branch?(ref)
  5 + can?(current_user, :push_code_to_protected_branches, project)
  6 + else
  7 + can?(current_user, :push_code, project)
  8 + end
  9 +
  10 + unless allowed
  11 + return error("You are not allowed to push into this branch")
  12 + end
  13 +
  14 + unless repository.branch_names.include?(ref)
  15 + return error("You can only create files if you are on top of a branch")
  16 + end
  17 +
  18 + blob = repository.blob_at(ref, path)
  19 +
  20 + unless blob
  21 + return error("You can only edit text files")
  22 + end
  23 +
  24 + delete_file_action = Gitlab::Satellite::DeleteFileAction.new(current_user, project, ref, path)
  25 +
  26 + deleted_successfully = delete_file_action.commit!(
  27 + nil,
  28 + params[:commit_message]
  29 + )
  30 +
  31 + if deleted_successfully
  32 + success
  33 + else
  34 + error("Your changes could not be commited, because the file has been changed")
  35 + end
  36 + end
  37 + end
  38 +end
... ...
app/controllers/projects/blob_controller.rb
... ... @@ -7,9 +7,30 @@ class Projects::BlobController &lt; Projects::ApplicationController
7 7 before_filter :authorize_code_access!
8 8 before_filter :require_non_empty_project
9 9  
  10 + before_filter :blob
  11 +
10 12 def show
11   - @blob = @repository.blob_at(@commit.id, @path)
  13 + end
  14 +
  15 + def destroy
  16 + result = Files::DeleteContext.new(@project, current_user, params, @ref, @path).execute
  17 +
  18 + if result[:status] == :success
  19 + flash[:notice] = "Your changes have been successfully commited"
  20 + redirect_to project_tree_path(@project, @ref)
  21 + else
  22 + flash[:alert] = result[:error]
  23 + render :show
  24 + end
  25 + end
  26 +
  27 + private
  28 +
  29 + def blob
  30 + @blob ||= @repository.blob_at(@commit.id, @path)
  31 +
  32 + return not_found! unless @blob
12 33  
13   - not_found! unless @blob
  34 + @blob
14 35 end
15 36 end
... ...
app/views/projects/blob/_actions.html.haml
... ... @@ -4,7 +4,7 @@
4 4 - if allowed_tree_edit?
5 5 = link_to "edit", project_edit_tree_path(@project, @id), class: "btn btn-small"
6 6 - else
7   - %span.btn.btn-small.disabled Edit
  7 + %span.btn.btn-small.disabled edit
8 8 = link_to "raw", project_raw_path(@project, @id), class: "btn btn-small", target: "_blank"
9 9 -# only show normal/blame view links for text files
10 10 - if @blob.text?
... ... @@ -13,3 +13,7 @@
13 13 - else
14 14 = link_to "blame", project_blame_path(@project, @id), class: "btn btn-small" unless @blob.empty?
15 15 = link_to "history", project_commits_path(@project, @id), class: "btn btn-small"
  16 +
  17 + - if allowed_tree_edit?
  18 + = link_to '#modal-remove-blob', class: "remove-blob btn btn-small btn-remove", "data-toggle" => "modal" do
  19 + remove
... ...
app/views/projects/blob/_remove.html.haml 0 → 100644
... ... @@ -0,0 +1,19 @@
  1 +%div#modal-remove-blob.modal.hide
  2 + .modal-header
  3 + %a.close{href: "#", "data-dismiss" => "modal"} ×
  4 + %h3.page-title Remove #{@blob.name}
  5 + %p.light
  6 + From branch
  7 + %strong= @ref
  8 +
  9 + .modal-body
  10 + = form_tag project_blob_path(@project, @id), method: :delete do
  11 + .control-group.commit_message-group
  12 + = label_tag 'commit_message', class: "control-label" do
  13 + Commit message
  14 + .controls
  15 + = text_area_tag 'commit_message', params[:commit_message], placeholder: "Removed this file because...", required: true, rows: 3
  16 + .control-group
  17 + .controls
  18 + = submit_tag 'Remove file', class: 'btn btn-remove'
  19 + = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal"
... ...
app/views/projects/blob/show.html.haml
... ... @@ -2,3 +2,6 @@
2 2 = render 'shared/ref_switcher', destination: 'blob', path: @path
3 3 %div#tree-holder.tree-holder
4 4 = render 'blob', blob: @blob
  5 +
  6 +- if allowed_tree_edit?
  7 + = render 'projects/blob/remove'
... ...
config/routes.rb
... ... @@ -173,7 +173,7 @@ Gitlab::Application.routes.draw do
173 173 end
174 174  
175 175 scope module: :projects do
176   - resources :blob, only: [:show], constraints: {id: /.+/}
  176 + resources :blob, only: [:show, :destroy], constraints: {id: /.+/}
177 177 resources :raw, only: [:show], constraints: {id: /.+/}
178 178 resources :tree, only: [:show], constraints: {id: /.+/, format: /(html|js)/ }
179 179 resources :edit_tree, only: [:show, :update], constraints: {id: /.+/}, path: 'edit'
... ...
lib/gitlab/satellite/files/delete_file_action.rb 0 → 100644
... ... @@ -0,0 +1,43 @@
  1 +require_relative 'file_action'
  2 +
  3 +module Gitlab
  4 + module Satellite
  5 + class DeleteFileAction < FileAction
  6 + # Deletes file and creates a new commit for it
  7 + #
  8 + # Returns false if committing the change fails
  9 + # Returns false if pushing from the satellite to bare repo failed or was rejected
  10 + # Returns true otherwise
  11 + def commit!(content, commit_message)
  12 + in_locked_and_timed_satellite do |repo|
  13 + prepare_satellite!(repo)
  14 +
  15 + # create target branch in satellite at the corresponding commit from bare repo
  16 + repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}")
  17 +
  18 + # update the file in the satellite's working dir
  19 + file_path_in_satellite = File.join(repo.working_dir, file_path)
  20 + File.delete(file_path_in_satellite)
  21 +
  22 + # add removed file
  23 + repo.remove(file_path_in_satellite)
  24 +
  25 + # commit the changes
  26 + # will raise CommandFailed when commit fails
  27 + repo.git.commit(raise: true, timeout: true, a: true, m: commit_message)
  28 +
  29 +
  30 + # push commit back to bare repo
  31 + # will raise CommandFailed when push fails
  32 + repo.git.push({raise: true, timeout: true}, :origin, ref)
  33 +
  34 + # everything worked
  35 + true
  36 + end
  37 + rescue Grit::Git::CommandFailed => ex
  38 + Gitlab::GitLogger.error(ex.message)
  39 + false
  40 + end
  41 + end
  42 + end
  43 +end
... ...
lib/gitlab/satellite/files/edit_file_action.rb
... ... @@ -8,13 +8,13 @@ module Gitlab
8 8 #
9 9 # Returns false if the ref has been updated while editing the file
10 10 # Returns false if committing the change fails
11   - # Returns false if pushing from the satellite to Gitolite failed or was rejected
  11 + # Returns false if pushing from the satellite to bare repo failed or was rejected
12 12 # Returns true otherwise
13 13 def commit!(content, commit_message)
14 14 in_locked_and_timed_satellite do |repo|
15 15 prepare_satellite!(repo)
16 16  
17   - # create target branch in satellite at the corresponding commit from Gitolite
  17 + # create target branch in satellite at the corresponding commit from bare repo
18 18 repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}")
19 19  
20 20 # update the file in the satellite's working dir
... ... @@ -26,7 +26,7 @@ module Gitlab
26 26 repo.git.commit(raise: true, timeout: true, a: true, m: commit_message)
27 27  
28 28  
29   - # push commit back to Gitolite
  29 + # push commit back to bare repo
30 30 # will raise CommandFailed when push fails
31 31 repo.git.push({raise: true, timeout: true}, :origin, ref)
32 32  
... ...
lib/gitlab/satellite/files/new_file_action.rb
... ... @@ -7,13 +7,13 @@ module Gitlab
7 7 #
8 8 # Returns false if the ref has been updated while editing the file
9 9 # Returns false if committing the change fails
10   - # Returns false if pushing from the satellite to Gitolite failed or was rejected
  10 + # Returns false if pushing from the satellite to bare repo failed or was rejected
11 11 # Returns true otherwise
12 12 def commit!(content, commit_message)
13 13 in_locked_and_timed_satellite do |repo|
14 14 prepare_satellite!(repo)
15 15  
16   - # create target branch in satellite at the corresponding commit from Gitolite
  16 + # create target branch in satellite at the corresponding commit from bare repo
17 17 repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}")
18 18  
19 19 # update the file in the satellite's working dir
... ... @@ -28,7 +28,7 @@ module Gitlab
28 28 repo.git.commit(raise: true, timeout: true, a: true, m: commit_message)
29 29  
30 30  
31   - # push commit back to Gitolite
  31 + # push commit back to bare repo
32 32 # will raise CommandFailed when push fails
33 33 repo.git.push({raise: true, timeout: true}, :origin, ref)
34 34  
... ...
lib/gitlab/satellite/merge_action.rb
... ... @@ -28,7 +28,7 @@ module Gitlab
28 28 in_locked_and_timed_satellite do |merge_repo|
29 29 prepare_satellite!(merge_repo)
30 30 if merge_in_satellite!(merge_repo)
31   - # push merge back to Gitolite
  31 + # push merge back to bare repo
32 32 # will raise CommandFailed when push fails
33 33 merge_repo.git.push(default_options, :origin, merge_request.target_branch)
34 34 # remove source branch
... ...
lib/gitlab/satellite/satellite.rb
... ... @@ -123,7 +123,7 @@ module Gitlab
123 123 remotes.each { |name| repo.git.remote(default_options,'rm', name)}
124 124 end
125 125  
126   - # Updates the satellite from Gitolite
  126 + # Updates the satellite from bare repo
127 127 #
128 128 # Note: this will only update remote branches (i.e. origin/*)
129 129 def update_from_source!
... ...