diff --git a/app/contexts/files/update_context.rb b/app/contexts/files/update_context.rb
new file mode 100644
index 0000000000000000000000000000000000000000..000d3d02f126211928efc4385f1c8353b15d14dd
--- /dev/null
+++ b/app/contexts/files/update_context.rb
@@ -0,0 +1,38 @@
+module Files
+  class UpdateContext < BaseContext
+    def execute
+      allowed = if project.protected_branch?(ref)
+                  can?(current_user, :push_code_to_protected_branches, project)
+                else
+                  can?(current_user, :push_code, project)
+                end
+
+      unless allowed
+        return error("You are not allowed to push into this branch")
+      end
+
+      unless repository.branch_names.include?(ref)
+        return error("You can only create files if you are on top of a branch")
+      end
+
+      blob = repository.blob_at(ref, path)
+
+      unless blob
+        return error("You can only edit text files")
+      end
+
+      new_file_action = Gitlab::Satellite::EditFileAction.new(current_user, project, ref, path)
+      created_successfully = new_file_action.commit!(
+        params[:content],
+        params[:commit_message],
+        params[:last_commit]
+      )
+
+      if created_successfully
+        success
+      else
+        error("Your changes could not be commited, because the file has been changed")
+      end
+    end
+  end
+end
diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb
index 8fd4565f3677fedeafd08578ef4acb365352f62d..80aeb5cd6cc04240aaf308d157a0dfbb429d9db5 100644
--- a/app/controllers/projects/application_controller.rb
+++ b/app/controllers/projects/application_controller.rb
@@ -23,4 +23,10 @@ class Projects::ApplicationController < ApplicationController
       'public_projects'
     end
   end
+
+  def require_branch_head
+    unless @repository.branch_names.include?(@ref)
+      redirect_to project_tree_path(@project, @ref), notice: "This action is not allowed unless you are on top of a branch"
+    end
+  end
 end
diff --git a/app/controllers/projects/base_tree_controller.rb b/app/controllers/projects/base_tree_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5e30593443311ddd50db57b90433b20e56e9b2ff
--- /dev/null
+++ b/app/controllers/projects/base_tree_controller.rb
@@ -0,0 +1,8 @@
+class Projects::BaseTreeController < Projects::ApplicationController
+  include ExtractsPath
+
+  before_filter :authorize_read_project!
+  before_filter :authorize_code_access!
+  before_filter :require_non_empty_project
+end
+
diff --git a/app/controllers/projects/edit_tree_controller.rb b/app/controllers/projects/edit_tree_controller.rb
index 0e51ff59f39297eb6d204ce5792d4ee36cc1a809..f6c547a020c27ef3ab41a80723d850ab6a9f7a52 100644
--- a/app/controllers/projects/edit_tree_controller.rb
+++ b/app/controllers/projects/edit_tree_controller.rb
@@ -1,53 +1,26 @@
-# Controller for edit a repository's file
-class Projects::EditTreeController < Projects::ApplicationController
-  include ExtractsPath
-
-  # Authorize
-  before_filter :authorize_read_project!
-  before_filter :authorize_code_access!
-  before_filter :require_non_empty_project
-
-  before_filter :edit_requirements, only: [:show, :update]
+class Projects::EditTreeController < Projects::BaseTreeController
+  before_filter :require_branch_head
+  before_filter :blob
 
   def show
     @last_commit = Gitlab::Git::Commit.last_for_path(@repository, @ref, @path).sha
   end
 
   def update
-    edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path)
-    updated_successfully = edit_file_action.commit!(
-      params[:content],
-      params[:commit_message],
-      params[:last_commit]
-    )
+    result = Files::UpdateContext.new(@project, current_user, params, @ref, @path).execute
 
-    if updated_successfully
-      redirect_to project_blob_path(@project, @id), notice: "Your changes have been successfully commited"
+    if result[:status] == :success
+      flash[:notice] = "Your changes have been successfully commited"
+      redirect_to project_blob_path(@project, @id)
     else
-      flash[:notice] = "Your changes could not be commited, because the file has been changed"
+      flash[:alert] = result[:error]
       render :show
     end
   end
 
   private
 
-  def edit_requirements
-    @blob = @repository.blob_at(@commit.id, @path)
-
-    unless @blob
-      redirect_to project_blob_path(@project, @id), notice: "You can only edit text files"
-    end
-
-    allowed = if project.protected_branch? @ref
-                can?(current_user, :push_code_to_protected_branches, project)
-              else
-                can?(current_user, :push_code, project)
-              end
-
-    return access_denied! unless allowed
-
-    unless @repository.branch_names.include?(@ref)
-      redirect_to project_blob_path(@project, @id), notice: "You can only edit this file if you are on top of a branch"
-    end
+  def blob
+    @blob ||= @repository.blob_at(@commit.id, @path)
   end
 end
diff --git a/app/controllers/projects/new_tree_controller.rb b/app/controllers/projects/new_tree_controller.rb
index 684c916055e2b753e56d53e50e69c243a921b4ba..9f9e0191e98cd713717c9fd064833e96c1f9bec2 100644
--- a/app/controllers/projects/new_tree_controller.rb
+++ b/app/controllers/projects/new_tree_controller.rb
@@ -1,10 +1,5 @@
-class Projects::NewTreeController < Projects::ApplicationController
-  include ExtractsPath
-
-  # Authorize
-  before_filter :authorize_read_project!
-  before_filter :authorize_code_access!
-  before_filter :require_non_empty_project
+class Projects::NewTreeController < Projects::BaseTreeController
+  before_filter :require_branch_head
 
   def show
   end
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index 1150efbea9d947b47e70046049a5bfbeb8bf1646..30c94ec6da0b0bbbcdc778320c96d32711f706c6 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -1,12 +1,5 @@
 # Controller for viewing a repository's file structure
-class Projects::TreeController < Projects::ApplicationController
-  include ExtractsPath
-
-  # Authorize
-  before_filter :authorize_read_project!
-  before_filter :authorize_code_access!
-  before_filter :require_non_empty_project
-
+class Projects::TreeController < Projects::BaseTreeController
   def show
     return not_found! if tree.entries.empty?