From e945ec02804bb28dbd228d8002a159c8da0fcc38 Mon Sep 17 00:00:00 2001
From: Douwe Maan <douwe@gitlab.com>
Date: Tue, 17 Nov 2015 18:53:56 +0100
Subject: [PATCH] Add "Start a new merge request" option to every commit form

---
 .../blob/blob_file_dropzone.js.coffee         | 17 ++----
 .../javascripts/blob/edit_blob.js.coffee      |  7 ---
 .../javascripts/blob/new_blob.js.coffee       |  7 ---
 .../javascripts/new_commit_form.js.coffee     | 21 ++++++++
 app/assets/stylesheets/pages/editor.scss      |  4 --
 app/controllers/application_controller.rb     | 30 -----------
 .../creates_merge_request_for_commit.rb       | 28 ++++++++++
 app/controllers/projects/blob_controller.rb   | 53 ++++++++++---------
 app/controllers/projects/tree_controller.rb   | 13 ++++-
 app/helpers/merge_requests_helper.rb          | 20 +++++++
 app/views/projects/blob/_actions.html.haml    |  2 +-
 app/views/projects/blob/_new_dir.html.haml    | 14 +++--
 app/views/projects/blob/_remove.html.haml     | 16 +++---
 app/views/projects/blob/_upload.html.haml     | 18 +++----
 app/views/projects/blob/edit.html.haml        | 19 ++-----
 app/views/projects/blob/new.html.haml         | 24 ++-------
 app/views/projects/blob/show.html.haml        |  4 +-
 .../projects/tree/_tree_content.html.haml     |  2 +-
 .../_commit_message_container.html.haml       |  8 +--
 app/views/shared/_new_commit_form.html.haml   | 18 +++++++
 20 files changed, 168 insertions(+), 157 deletions(-)
 create mode 100644 app/assets/javascripts/new_commit_form.js.coffee
 create mode 100644 app/controllers/concerns/creates_merge_request_for_commit.rb
 create mode 100644 app/views/shared/_new_commit_form.html.haml

diff --git a/app/assets/javascripts/blob/blob_file_dropzone.js.coffee b/app/assets/javascripts/blob/blob_file_dropzone.js.coffee
index 5b604adbbb1..195f8b11e5d 100644
--- a/app/assets/javascripts/blob/blob_file_dropzone.js.coffee
+++ b/app/assets/javascripts/blob/blob_file_dropzone.js.coffee
@@ -23,18 +23,6 @@ class @BlobFileDropzone
       init: ->
         this.on 'addedfile', (file) ->
           $('.dropzone-alerts').html('').hide()
-          commit_message = form.find('#commit_message')[0]
-
-          if /^Upload/.test(commit_message.placeholder)
-            commit_message.placeholder = 'Upload ' + file.name
-
-          return
-
-        this.on 'removedfile', (file) ->
-          commit_message = form.find('#commit_message')[0]
-
-          if /^Upload/.test(commit_message.placeholder)
-            commit_message.placeholder = 'Upload new file'
 
           return
 
@@ -47,8 +35,9 @@ class @BlobFileDropzone
           return
 
         this.on 'sending', (file, xhr, formData) ->
-          formData.append('new_branch', form.find('#new_branch').val())
-          formData.append('commit_message', form.find('#commit_message').val())
+          formData.append('new_branch', form.find('.js-new-branch').val())
+          formData.append('create_merge_request', form.find('.js-create-merge-request').val())
+          formData.append('commit_message', form.find('.js-commit-message').val())
           return
 
       # Override behavior of adding error underneath preview
diff --git a/app/assets/javascripts/blob/edit_blob.js.coffee b/app/assets/javascripts/blob/edit_blob.js.coffee
index bf4cd85aee0..f6bf836f19f 100644
--- a/app/assets/javascripts/blob/edit_blob.js.coffee
+++ b/app/assets/javascripts/blob/edit_blob.js.coffee
@@ -11,13 +11,6 @@ class @EditBlob
     if ace_mode
       editor.getSession().setMode "ace/mode/" + ace_mode
 
-    $('#new_branch').keyup ->
-      if $(this).val() != $('#original_branch').val()
-        $('.form-group.destination').show()
-      else
-        $('.form-group.destination').hide()
-        $('#create_merge_request').prop('checked', false)
-
     # Before a form submission, move the content from the Ace editor into the
     # submitted textarea
     $('form').submit ->
diff --git a/app/assets/javascripts/blob/new_blob.js.coffee b/app/assets/javascripts/blob/new_blob.js.coffee
index c2d6c7acfef..68c5e5195e3 100644
--- a/app/assets/javascripts/blob/new_blob.js.coffee
+++ b/app/assets/javascripts/blob/new_blob.js.coffee
@@ -11,13 +11,6 @@ class @NewBlob
     if ace_mode
       editor.getSession().setMode "ace/mode/" + ace_mode
 
-    $('#new_branch').keyup ->
-      if $(this).val() != $('#original_branch').val()
-        $('.form-group.destination').show()
-      else
-        $('.form-group.destination').hide()
-        $('#create_merge_request').prop('checked', false)
-
     # Before a form submission, move the content from the Ace editor into the
     # submitted textarea
     $('form').submit ->
diff --git a/app/assets/javascripts/new_commit_form.js.coffee b/app/assets/javascripts/new_commit_form.js.coffee
new file mode 100644
index 00000000000..2e561dea3e1
--- /dev/null
+++ b/app/assets/javascripts/new_commit_form.js.coffee
@@ -0,0 +1,21 @@
+class @NewCommitForm
+  constructor: (form) ->
+    @newBranch = form.find('.js-new-branch')
+    @originalBranch = form.find('.js-original-branch')
+    @createMergeRequest = form.find('.js-create-merge-request')
+    @createMergeRequestFormGroup = form.find('.js-create-merge-request-form-group')
+
+    @renderDestination()
+    @newBranch.keyup @renderDestination
+
+  renderDestination: =>
+    different = @newBranch.val() != @originalBranch.val()
+
+    if different
+      @createMergeRequestFormGroup.show()
+      @createMergeRequest.prop('checked', true) unless @wasDifferent
+    else
+      @createMergeRequestFormGroup.hide()
+      @createMergeRequest.prop('checked', false)
+
+    @wasDifferent = different
diff --git a/app/assets/stylesheets/pages/editor.scss b/app/assets/stylesheets/pages/editor.scss
index c0defa82bff..e2c521af91e 100644
--- a/app/assets/stylesheets/pages/editor.scss
+++ b/app/assets/stylesheets/pages/editor.scss
@@ -63,8 +63,4 @@
     margin-top: 0;
     padding: $gl-padding
   }
-
-  .destination {
-    display: none;
-  }
 }
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 6f87ee08b2d..0d182e8eb04 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -22,7 +22,6 @@ class ApplicationController < ActionController::Base
 
   helper_method :abilities, :can?, :current_application_settings
   helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled?
-  helper_method :new_mr_from_push_event, :new_mr_path_for_fork_from_push_event, :new_mr_path_from_push_event
 
   rescue_from Encoding::CompatibilityError do |exception|
     log_exception(exception)
@@ -343,35 +342,6 @@ class ApplicationController < ActionController::Base
     current_application_settings.import_sources.include?('git')
   end
 
-  # new merge requests routing helpers
-  def new_mr_path_from_push_event(event, target_branch=nil)
-    target_project = event.project.forked_from_project || event.project
-    new_namespace_project_merge_request_path(
-      event.project.namespace,
-      event.project,
-      new_mr_from_push_event(event, target_project, target_branch)
-    )
-  end
-
-  def new_mr_path_for_fork_from_push_event(event, target_branch=nil)
-    new_namespace_project_merge_request_path(
-      event.project.namespace,
-      event.project,
-      new_mr_from_push_event(event, event.project.forked_from_project, target_branch)
-    )
-  end
-
-  def new_mr_from_push_event(event, target_project, target_branch)
-    {
-      merge_request: {
-        source_project_id: event.project.id,
-        target_project_id: target_project.id,
-        source_branch: event.branch_name,
-        target_branch: target_branch || target_project.repository.root_ref
-      }
-    }
-  end
-
   def redirect_to_home_page_url?
     # If user is not signed-in and tries to access root_path - redirect him to landing page
     # Don't redirect to the default URL to prevent endless redirections
diff --git a/app/controllers/concerns/creates_merge_request_for_commit.rb b/app/controllers/concerns/creates_merge_request_for_commit.rb
new file mode 100644
index 00000000000..c7527822158
--- /dev/null
+++ b/app/controllers/concerns/creates_merge_request_for_commit.rb
@@ -0,0 +1,28 @@
+module CreatesMergeRequestForCommit
+  extend ActiveSupport::Concern
+
+  def new_merge_request_path
+    if @project.forked?
+      target_project = @project.forked_from_project || @project
+      target_branch = target_project.repository.root_ref
+    else
+      target_project = @project
+      target_branch = @ref
+    end
+
+    new_namespace_project_merge_request_path(
+      @project.namespace,
+      @project,
+      merge_request: {
+        source_project_id: @project.id,
+        target_project_id: target_project.id,
+        source_branch: @new_branch,
+        target_branch: target_branch
+      }
+    )
+  end
+
+  def create_merge_request?
+    params[:create_merge_request] && @new_branch != @ref
+  end
+end
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index d7fae64fcdd..41ec7bde45d 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -1,6 +1,7 @@
 # Controller for viewing a file's blame
 class Projects::BlobController < Projects::ApplicationController
   include ExtractsPath
+  include CreatesMergeRequestForCommit
   include ActionView::Helpers::SanitizeHelper
 
   # Raised when given an invalid file path
@@ -27,15 +28,8 @@ class Projects::BlobController < Projects::ApplicationController
     if result[:status] == :success
       flash[:notice] = "The changes have been successfully committed"
       respond_to do |format|
-        format.html do
-          url = if params[:create_merge_request]
-            new_mr_path_from_push_event(current_user.recent_push(@project.id), @ref)
-          else
-            namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @file_path))
-          end
-          redirect_to url
-        end
-        format.json { render json: { message: "success", filePath: namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @file_path)) } }
+        format.html { redirect_to after_create_path }
+        format.json { render json: { message: "success", filePath: after_create_path } }
       end
     else
       flash[:alert] = result[:message]
@@ -59,14 +53,7 @@ class Projects::BlobController < Projects::ApplicationController
     if result[:status] == :success
       flash[:notice] = "Your changes have been successfully committed"
       respond_to do |format|
-        format.html do
-          url = if params[:create_merge_request]
-            new_mr_path_from_push_event(current_user.recent_push(@project.id), @ref)
-          else
-            after_edit_path
-          end
-          redirect_to url
-        end
+        format.html { redirect_to after_edit_path }
         format.json { render json: { message: "success", filePath: after_edit_path } }
       end
     else
@@ -91,7 +78,7 @@ class Projects::BlobController < Projects::ApplicationController
 
     if result[:status] == :success
       flash[:notice] = "Your changes have been successfully committed"
-      redirect_to namespace_project_tree_path(@project.namespace, @project, @target_branch)
+      redirect_to after_destroy_path
     else
       flash[:alert] = result[:message]
       render :show
@@ -145,15 +132,33 @@ class Projects::BlobController < Projects::ApplicationController
     render_404
   end
 
+  def after_create_path
+    @after_create_path ||=
+      if create_merge_request?
+        new_merge_request_path
+      else
+        namespace_project_blob_path(@project.namespace, @project, File.join(@new_branch, @file_path))
+      end
+  end
+
   def after_edit_path
     @after_edit_path ||=
-      if from_merge_request
+      if create_merge_request?
+        new_merge_request_path
+      elsif from_merge_request && @new_branch == @ref
         diffs_namespace_project_merge_request_path(from_merge_request.target_project.namespace, from_merge_request.target_project, from_merge_request) +
           "#file-path-#{hexdigest(@path)}"
-      elsif @target_branch.present?
-        namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @path))
       else
-        namespace_project_blob_path(@project.namespace, @project, @id)
+        namespace_project_blob_path(@project.namespace, @project, File.join(@new_branch, @path))
+      end
+  end
+
+  def after_destroy_path
+    @after_destroy_path ||=
+      if create_merge_request?
+        new_merge_request_path
+      else
+        namespace_project_tree_path(@project.namespace, @project, @new_branch)
       end
   end
 
@@ -168,7 +173,7 @@ class Projects::BlobController < Projects::ApplicationController
 
   def editor_variables
     @current_branch = @ref
-    @target_branch = params[:new_branch].present? ? sanitized_new_branch_name : @ref
+    @new_branch = params[:new_branch].present? ? sanitized_new_branch_name : @ref
 
     @file_path =
       if action_name.to_s == 'create'
@@ -188,7 +193,7 @@ class Projects::BlobController < Projects::ApplicationController
     @commit_params = {
       file_path: @file_path,
       current_branch: @current_branch,
-      target_branch: @target_branch,
+      target_branch: @new_branch,
       commit_message: params[:commit_message],
       file_content: params[:content],
       file_content_encoding: params[:encoding]
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index bdcb1a3e297..8f272ad1281 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -1,6 +1,7 @@
 # Controller for viewing a repository's file structure
 class Projects::TreeController < Projects::ApplicationController
   include ExtractsPath
+  include CreatesMergeRequestForCommit
   include ActionView::Helpers::SanitizeHelper
 
   before_action :require_non_empty_project, except: [:new, :create]
@@ -43,7 +44,7 @@ class Projects::TreeController < Projects::ApplicationController
     if result && result[:status] == :success
       flash[:notice] = "The directory has been successfully created"
       respond_to do |format|
-        format.html { redirect_to namespace_project_blob_path(@project.namespace, @project, File.join(@new_branch, @dir_name)) }
+        format.html { redirect_to after_create_dir_path }
       end
     else
       flash[:alert] = message
@@ -53,6 +54,8 @@ class Projects::TreeController < Projects::ApplicationController
     end
   end
 
+  private
+
   def assign_dir_vars
     @new_branch = params[:new_branch].present? ? sanitize(strip_tags(params[:new_branch])) : @ref
     @dir_name = File.join(@path, params[:dir_name])
@@ -63,4 +66,12 @@ class Projects::TreeController < Projects::ApplicationController
       commit_message: params[:commit_message],
     }
   end
+
+  def after_create_dir_path
+    if create_merge_request?
+      new_merge_request_path
+    else
+      namespace_project_blob_path(@project.namespace, @project, File.join(@new_branch, @dir_name))
+    end
+  end
 end
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 7e8f61fd274..b804d4f4e3b 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -1,4 +1,24 @@
 module MergeRequestsHelper
+  def new_mr_path_from_push_event(event)
+    target_project = event.project.forked_from_project || event.project
+    new_namespace_project_merge_request_path(
+      event.project.namespace,
+      event.project,
+      new_mr_from_push_event(event, target_project)
+    )
+  end
+
+  def new_mr_from_push_event(event, target_project)
+    {
+      merge_request: {
+        source_project_id: event.project.id,
+        target_project_id: target_project.id,
+        source_branch: event.branch_name,
+        target_branch: target_project.repository.root_ref
+      }
+    }
+  end
+
   def mr_css_classes(mr)
     classes = "merge-request"
     classes << " closed" if mr.closed?
diff --git a/app/views/projects/blob/_actions.html.haml b/app/views/projects/blob/_actions.html.haml
index 373b3a0c5b0..ba3e0c3c590 100644
--- a/app/views/projects/blob/_actions.html.haml
+++ b/app/views/projects/blob/_actions.html.haml
@@ -19,4 +19,4 @@
 - if allowed_tree_edit?
   .btn-group{ role: "group" }
     %button.btn.btn-default{ 'data-target' => '#modal-upload-blob', 'data-toggle' => 'modal' } Replace
-    %button.btn.btn-remove{ 'data-target' => '#modal-remove-blob', 'data-toggle' => 'modal' } Remove
+    %button.btn.btn-remove{ 'data-target' => '#modal-remove-blob', 'data-toggle' => 'modal' } Delete
diff --git a/app/views/projects/blob/_new_dir.html.haml b/app/views/projects/blob/_new_dir.html.haml
index a0fc8bbd752..13b5ffd17ff 100644
--- a/app/views/projects/blob/_new_dir.html.haml
+++ b/app/views/projects/blob/_new_dir.html.haml
@@ -5,21 +5,19 @@
         %a.close{href: "#", "data-dismiss" => "modal"} ×
         %h3.page-title Create New Directory
       .modal-body
-        = form_tag namespace_project_create_dir_path(@project.namespace, @project, @id), method: :post, remote: false, id: 'dir-create-form', class: 'form-horizontal' do
+        = form_tag namespace_project_create_dir_path(@project.namespace, @project, @id), method: :post, remote: false, class: 'form-horizontal js-create-dir-form' do
           .form-group
             = label_tag :dir_name, 'Directory Name', class: 'control-label'
             .col-sm-10
               = text_field_tag :dir_name, params[:dir_name], placeholder: "Directory name", required: true, class: 'form-control'
-          = render 'shared/commit_message_container', params: params, placeholder: ''
-          - unless @project.empty_repo?
-            .form-group
-              = label_tag :branch_name, 'Branch', class: 'control-label'
-              .col-sm-10
-                = text_field_tag 'new_branch', @ref, class: "form-control"
+
+          = render 'shared/new_commit_form', placeholder: "Add new directory"
+
           .form-group
             .col-sm-offset-2.col-sm-10
               = submit_tag "Create directory", class: 'btn btn-primary btn-create'
               = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal"
 
 :javascript
-  disableButtonIfAnyEmptyField($("#dir-create-form"), ".form-control", ".btn-create");
+  disableButtonIfAnyEmptyField($(".js-create-dir-form"), ".form-control", ".btn-create");
+  new NewCommitForm($('.js-create-dir-form'))
diff --git a/app/views/projects/blob/_remove.html.haml b/app/views/projects/blob/_remove.html.haml
index cae5ff01099..1cf19a7d3db 100644
--- a/app/views/projects/blob/_remove.html.haml
+++ b/app/views/projects/blob/_remove.html.haml
@@ -3,16 +3,16 @@
     .modal-content
       .modal-header
         %a.close{href: "#", "data-dismiss" => "modal"} ×
-        %h3.page-title Remove #{@blob.name}
-        %p.light
-          From branch
-          %strong= @ref
+        %h3.page-title Delete #{@blob.name}
 
       .modal-body
-        = form_tag namespace_project_blob_path(@project.namespace, @project, @id), method: :delete, class: 'form-horizontal js-requires-input' do
-          = render 'shared/commit_message_container', params: params,
-                   placeholder: 'Removed this file because...'
+        = form_tag namespace_project_blob_path(@project.namespace, @project, @id), method: :delete, class: 'form-horizontal js-replace-blob-form js-requires-input' do
+          = render 'shared/new_commit_form', placeholder: "Delete #{@blob.name}"
+
           .form-group
             .col-sm-offset-2.col-sm-10
-              = button_tag 'Remove file', class: 'btn btn-remove btn-remove-file'
+              = button_tag 'Delete file', class: 'btn btn-remove btn-remove-file'
               = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal"
+
+:javascript
+  new NewCommitForm($('.js-replace-blob-form'))
diff --git a/app/views/projects/blob/_upload.html.haml b/app/views/projects/blob/_upload.html.haml
index a1c54e731f0..3bb61f0c944 100644
--- a/app/views/projects/blob/_upload.html.haml
+++ b/app/views/projects/blob/_upload.html.haml
@@ -5,7 +5,7 @@
         %a.close{href: "#", "data-dismiss" => "modal"} ×
         %h3.page-title #{title}
       .modal-body
-        = form_tag form_path, method: method, class: 'blob-file-upload-form-js form-horizontal' do
+        = form_tag form_path, method: method, class: 'js-upload-blob-form form-horizontal' do
           .dropzone
             .dropzone-previews.blob-upload-dropzone-previews
               %p.dz-message.light
@@ -13,19 +13,15 @@
                 = link_to 'click to upload', '#', class: "markdown-selector"
           %br
           .dropzone-alerts{class: "alert alert-danger data", style: "display:none"}
-          = render 'shared/commit_message_container', params: params,
-            placeholder: placeholder
-          - unless @project.empty_repo?
-            .form-group.branch
-              = label_tag 'branch', class: 'control-label' do
-                Branch
-              .col-sm-10
-                = text_field_tag 'new_branch', @ref, class: "form-control"
+
+          = render 'shared/new_commit_form', placeholder: placeholder
+
           .form-group
             .col-sm-offset-2.col-sm-10
               = button_tag button_title, class: 'btn btn-small btn-primary btn-upload-file', id: 'submit-all'
               = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal"
 
 :javascript
-  disableButtonIfEmptyField($('.blob-file-upload-form-js').find('#commit_message'), '.btn-upload-file');
-  new BlobFileDropzone($('.blob-file-upload-form-js'), '#{method}');
+  disableButtonIfEmptyField($('.js-upload-blob-form').find('.js-commit-message'), '.btn-upload-file');
+  new BlobFileDropzone($('.js-upload-blob-form'), '#{method}');
+  new NewCommitForm($('.js-upload-blob-form'))
diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml
index 26216462707..56745165251 100644
--- a/app/views/projects/blob/edit.html.haml
+++ b/app/views/projects/blob/edit.html.haml
@@ -13,28 +13,15 @@
         %i.fa.fa-eye
         = editing_preview_title(@blob.name)
 
-  = form_tag(namespace_project_update_blob_path(@project.namespace, @project, @id), method: :put, class: 'form-horizontal js-requires-input') do
+  = form_tag(namespace_project_update_blob_path(@project.namespace, @project, @id), method: :put, class: 'form-horizontal js-requires-input js-edit-blob-form') do
     = render 'projects/blob/editor', ref: @ref, path: @path, blob_data: @blob.data
-    = render 'shared/commit_message_container', params: params, placeholder: "Update #{@blob.name}"
-
-    .form-group.branch
-      = label_tag 'branch', class: 'control-label' do
-        Branch
-      .col-sm-10
-        = text_field_tag 'new_branch', @ref, class: "form-control"
-
-    .form-group.destination
-      .col-sm-offset-2.col-sm-10
-        .checkbox
-          = label_tag :create_merge_request do
-            = check_box_tag :create_merge_request, 1, false
-            Start a new merge request
+    = render 'shared/new_commit_form', placeholder: "Update #{@blob.name}"
 
     = hidden_field_tag 'last_commit', @last_commit
     = hidden_field_tag 'content', '', id: "file-content"
     = hidden_field_tag 'from_merge_request_id', params[:from_merge_request_id]
-    = hidden_field_tag 'original_branch', @ref
     = render 'projects/commit_button', ref: @ref, cancel_path: @after_edit_path
 
 :javascript
   blob = new EditBlob(gon.relative_url_root + "#{Gitlab::Application.config.assets.prefix}", "#{@blob.language.try(:ace_mode)}")
+  new NewCommitForm($('.js-edit-blob-form'))
diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml
index 0439e55131e..1ff68005450 100644
--- a/app/views/projects/blob/new.html.haml
+++ b/app/views/projects/blob/new.html.haml
@@ -2,32 +2,18 @@
 = render "header_title"
 
 .gray-content-block.top-block
-  Create a new file
+  %h3.page-title
+    Create New File
 
 .file-editor
-  = form_tag(namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post, class: 'form-horizontal form-new-file js-requires-input') do
+  = form_tag(namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post, class: 'form-horizontal js-new-blob-form js-requires-input') do
     = render 'projects/blob/editor', ref: @ref
-    = render 'shared/commit_message_container', params: params,
-             placeholder: 'Add new file'
-
-    - unless @project.empty_repo?
-      .form-group.branch
-        = label_tag 'branch', class: 'control-label' do
-          Branch
-        .col-sm-10
-          = text_field_tag 'new_branch', @ref, class: "form-control js-quick-submit"
-
-      .form-group.destination
-        .col-sm-offset-2.col-sm-10
-          .checkbox
-            = label_tag :create_merge_request do
-              = check_box_tag :create_merge_request, 1, false
-              Start a new merge request
+    = render 'shared/new_commit_form', placeholder: "Add new file"
 
     = hidden_field_tag 'content', '', id: 'file-content'
-    = hidden_field_tag 'original_branch', @ref
     = render 'projects/commit_button', ref: @ref,
               cancel_path: namespace_project_tree_path(@project.namespace, @project, @id)
 
 :javascript
   blob = new NewBlob(gon.relative_url_root + "#{Gitlab::Application.config.assets.prefix}", null)
+  new NewCommitForm($('.js-new-blob-form'))
diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml
index f52b89f6921..b7276868ce6 100644
--- a/app/views/projects/blob/show.html.haml
+++ b/app/views/projects/blob/show.html.haml
@@ -10,6 +10,4 @@
   = render 'projects/blob/remove'
 
   - title = "Replace #{@blob.name}"
-  = render 'projects/blob/upload', title: title, placeholder: title,
-    button_title: 'Replace file', form_path: namespace_project_update_blob_path(@project.namespace, @project, @id),
-    method: :put
+  = render 'projects/blob/upload', title: title, placeholder: title, button_title: 'Replace file', form_path: namespace_project_update_blob_path(@project.namespace, @project, @id), method: :put
diff --git a/app/views/projects/tree/_tree_content.html.haml b/app/views/projects/tree/_tree_content.html.haml
index ee4c9d1693d..c64e684df26 100644
--- a/app/views/projects/tree/_tree_content.html.haml
+++ b/app/views/projects/tree/_tree_content.html.haml
@@ -30,7 +30,7 @@
     = render "projects/tree/readme", readme: tree.readme
 
 - if allowed_tree_edit?
-  = render 'projects/blob/upload', title: 'Upload', placeholder: 'Upload new file', button_title: 'Upload file', form_path: namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post
+  = render 'projects/blob/upload', title: 'Upload New File', placeholder: 'Upload new file', button_title: 'Upload file', form_path: namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post
   = render 'projects/blob/new_dir'
 
 :javascript
diff --git a/app/views/shared/_commit_message_container.html.haml b/app/views/shared/_commit_message_container.html.haml
index cc3f1268f8b..7c57924277e 100644
--- a/app/views/shared/_commit_message_container.html.haml
+++ b/app/views/shared/_commit_message_container.html.haml
@@ -1,13 +1,15 @@
 .form-group.commit_message-group
-  = label_tag 'commit_message', class: 'control-label' do
+  - nonce = SecureRandom.hex
+  = label_tag "commit_message-#{nonce}", class: 'control-label' do
     Commit message
   .col-sm-10
     .commit-message-container
       .max-width-marker
       = text_area_tag 'commit_message',
           (params[:commit_message] || local_assigns[:text]),
-          class: 'form-control js-quick-submit', placeholder: local_assigns[:placeholder],
-          required: true, rows: (local_assigns[:rows] || 3)
+          class: 'form-control js-commit-message js-quick-submit', placeholder: local_assigns[:placeholder],
+          required: true, rows: (local_assigns[:rows] || 3),
+          id: "commit_message-#{nonce}"
     - if local_assigns[:hint]
       %p.hint
         Try to keep the first line under 52 characters
diff --git a/app/views/shared/_new_commit_form.html.haml b/app/views/shared/_new_commit_form.html.haml
new file mode 100644
index 00000000000..8636341c60d
--- /dev/null
+++ b/app/views/shared/_new_commit_form.html.haml
@@ -0,0 +1,18 @@
+= render 'shared/commit_message_container', placeholder: placeholder
+
+- unless @project.empty_repo?
+  .form-group.branch
+    = label_tag 'branch', class: 'control-label' do
+      Branch
+    .col-sm-10
+      = text_field_tag 'new_branch', @new_branch || @ref, class: "form-control js-new-branch"
+
+  .form-group.js-create-merge-request-form-group
+    .col-sm-offset-2.col-sm-10
+      .checkbox
+        - nonce = SecureRandom.hex
+        = label_tag "create_merge_request-#{nonce}" do
+          = check_box_tag 'create_merge_request', 1, true, class: 'js-create-merge-request', id: "create_merge_request-#{nonce}"
+          Start a <strong>new merge request</strong> with this commit
+
+  = hidden_field_tag 'original_branch', @ref, class: 'js-original-branch'
-- 
GitLab