diff --git a/CHANGELOG b/CHANGELOG
index 3866153b3b8e1d712ec87d39f709a303067fcec8..e1252d4b947c8b5b4cb1c46976c497e3ca8b3504 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,7 @@ v 8.8.0 (unreleased)
   - Fix error when using link to uploads in global snippets
   - Assign labels and milestone to target project when moving issue. !3934 (Long Nguyen)
   - Use a case-insensitive comparison in sanitizing URI schemes
+  - Toggle sign-up confirmation emails in application settings
   - Project#open_branches has been cleaned up and no longer loads entire records into memory.
   - Escape HTML in commit titles in system note messages
   - Improve multiple branch push performance by memoizing permission checking
@@ -15,6 +16,7 @@ v 8.8.0 (unreleased)
   - Make build status canceled if any of the jobs was canceled and none failed
   - Upgrade Sidekiq to 4.1.2
   - Added /health_check endpoint for checking service status
+  - Make 'upcoming' filter for milestones work better across projects
   - Sanitize repo paths in new project error message
   - Bump mail_room to 0.7.0 to fix stuck IDLE connections
   - Remove future dates from contribution calendar graph.
@@ -29,6 +31,7 @@ v 8.8.0 (unreleased)
   - Display informative message when new milestone is created
   - Sanitize milestones and labels titles
   - Support multi-line tag messages. !3833 (Calin Seciu)
+  - Force users to reset their password after an admin changes it
   - Allow "NEWS" and "CHANGES" as alternative names for CHANGELOG. !3768 (Connor Shea)
   - Added button to toggle whitespaces changes on diff view
   - Backport GitHub Enterprise import support from EE
@@ -44,7 +47,7 @@ v 8.8.0 (unreleased)
   - API support for the 'since' and 'until' operators on commit requests (Paco Guzman)
   - Fix Gravatar hint in user profile when Gravatar is disabled. !3988 (Artem Sidorenko)
   - Expire repository exists? and has_visible_content? caches after a push if necessary
-  - Fix unintentional filtering bug in issues sorted by milestone due (Takuya Noguchi)
+  - Fix unintentional filtering bug in Issue/MR sorted by milestone due (Takuya Noguchi)
   - Fix adding a todo for private group members (Ahmad Sherif)
   - Bump ace-rails-ap gem version from 2.0.1 to 4.0.2 which upgrades Ace Editor from 1.1.2 to 1.2.3
   - Total method execution timings are no longer tracked
@@ -52,6 +55,11 @@ v 8.8.0 (unreleased)
   - Add API endpoints for un/subscribing from/to a label. !4051 (Ahmad Sherif)
   - Hide left sidebar on phone screens to give more space for content
   - Redesign navigation for profile and group pages
+  - Add counter metrics for rails cache
+  - Import pull requests from GitHub where the source or target branches were removed
+
+v 8.7.6
+  - Fix links on wiki pages for relative url setups. !4131 (Artem Sidorenko)
 
 v 8.7.5
   - Fix relative links in wiki pages. !4050
diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee
index efb3e8e219817a571610fe00b05e31d08b14f2b7..6d9d6528f454dd18e34aebeeac00868c5581ec0a 100644
--- a/app/assets/javascripts/notes.js.coffee
+++ b/app/assets/javascripts/notes.js.coffee
@@ -285,6 +285,7 @@ class @Notes
     form.addClass "js-main-target-form"
 
     form.find("#note_line_code").remove()
+    form.find("#note_type").remove()
 
   ###
   General note form setup.
@@ -472,6 +473,7 @@ class @Notes
   setupDiscussionNoteForm: (dataHolder, form) =>
     # setup note target
     form.attr 'id', "new-discussion-note-form-#{dataHolder.data("discussionId")}"
+    form.find("#note_type").val dataHolder.data("noteType")
     form.find("#line_type").val dataHolder.data("lineType")
     form.find("#note_commit_id").val dataHolder.data("commitId")
     form.find("#note_line_code").val dataHolder.data("lineCode")
diff --git a/app/assets/stylesheets/framework/gitlab-theme.scss b/app/assets/stylesheets/framework/gitlab-theme.scss
index 51a17d1469e48526ac4060b09e3eeee1a35d6a18..f47eb1f233ebd5316e5d13c51f546be78ede62c8 100644
--- a/app/assets/stylesheets/framework/gitlab-theme.scss
+++ b/app/assets/stylesheets/framework/gitlab-theme.scss
@@ -88,8 +88,8 @@
 }
 
 $theme-blue: #2980b9;
-$theme-charcoal: #333c47;
-$theme-graphite: #888;
+$theme-charcoal: #3d454d;
+$theme-graphite: #666;
 $theme-gray: #373737;
 $theme-green: #019875;
 $theme-violet: #548;
@@ -100,11 +100,11 @@ body {
   }
 
   &.ui_charcoal {
-    @include gitlab-theme(#c5d0de, $theme-charcoal, #2b333d, #24272d);
+    @include gitlab-theme(#d6d7d9, #485157, $theme-charcoal, #353b41);
   }
 
   &.ui_graphite {
-    @include gitlab-theme(#ccc, $theme-graphite, #777, #666);
+    @include gitlab-theme(#ccc, #777, $theme-graphite, #555);
   }
 
   &.ui_gray {
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index 624c8249f7e154dbc633c4176706c667017b3797..a3e1ac13a4374fe0a9d15e86f7fa417508a29693 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -226,8 +226,7 @@ ul.notes {
   }
 }
 
-.note-action-button,
-.discussion-action-button {
+.note-action-button {
   display: inline-block;
   margin-left: 10px;
   line-height: 24px;
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 8c973f0e4a882e9c0d782032984d8d4238b0ffde..ff7a5cad2fb9d3b0baf66e5d10722bd212cc25f5 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -106,6 +106,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
       :email_author_in_body,
       :repository_checks_enabled,
       :metrics_packet_size,
+      :send_user_confirmation_email,
       restricted_visibility_levels: [],
       import_sources: [],
       disabled_oauth_sign_in_sources: []
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index f2f654c7bcdeb37c77454da89c266a3c850266e4..6908a3bf946e94a16bec1411b02d8db70113af45 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -119,6 +119,7 @@ class Admin::UsersController < Admin::ApplicationController
       user_params_with_pass.merge!(
         password: params[:user][:password],
         password_confirmation: params[:user][:password_confirmation],
+        password_expires_at: Time.now
       )
     end
 
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index a202cb38692cd9eb0a5cb239cddbe82c8bc5db7c..10b5932affabb60049a2fc3fc5164280fd7cd33d 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -17,12 +17,12 @@ class Projects::CommitController < Projects::ApplicationController
   def show
     apply_diff_view_cookie!
 
-    @line_notes = commit.notes.inline
+    @grouped_diff_notes = commit.notes.grouped_diff_notes
+
     @note = @project.build_commit_note(commit)
-    @notes = commit.notes.not_inline.fresh
+    @notes = commit.notes.non_diff_notes.fresh
     @noteable = @commit
-    @comments_allowed = @reply_allowed = true
-    @comments_target  = {
+    @comments_target = {
       noteable_type: 'Commit',
       commit_id: @commit.id
     }
@@ -67,10 +67,10 @@ class Projects::CommitController < Projects::ApplicationController
     create_commit(Commits::RevertService, success_notice: "The #{@commit.change_type_title} has been successfully reverted.",
                                           success_path: successful_change_path, failure_path: failed_change_path)
   end
-  
+
   def cherry_pick
     assign_change_commit_vars(@commit.cherry_pick_branch_name)
-    
+
     return render_404 if @target_branch.blank?
 
     create_commit(Commits::CherryPickService, success_notice: "The #{@commit.change_type_title} has been successfully cherry-picked.",
diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb
index 671d5c2302488f514d34ccdb26699b87815d5566..af0b69a2442321adb371733a119f41641e9cff56 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -22,7 +22,8 @@ class Projects::CompareController < Projects::ApplicationController
       @base_commit = @project.merge_base_commit(@base_ref, @head_ref)
       @diffs = compare.diffs(diff_options)
       @diff_refs = [@base_commit, @commit]
-      @line_notes = []
+      @diff_notes_disabled = true
+      @grouped_diff_notes = {}
     end
   end
 
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 9c147b3689ebac7d906140cdc443164a23a369a9..c5757a24624754f18187a6502d38ac3443bdca3a 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -73,12 +73,12 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     # but we need it for the "View file @ ..." link by deleted files
     @base_commit ||= @merge_request.first_commit.parent || @merge_request.first_commit
 
-    @comments_allowed = @reply_allowed = true
     @comments_target = {
       noteable_type: 'MergeRequest',
       noteable_id: @merge_request.id
     }
-    @line_notes = @merge_request.notes.where("line_code is not null")
+
+    @grouped_diff_notes = @merge_request.notes.grouped_diff_notes
 
     respond_to do |format|
       format.html
@@ -117,6 +117,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     @commit = @merge_request.last_commit
     @base_commit = @merge_request.diff_base_commit
     @diffs = @merge_request.compare.diffs(diff_options) if @merge_request.compare
+    @diff_notes_disabled = true
 
     @ci_commit = @merge_request.ci_commit
     @statuses = @ci_commit.statuses if @ci_commit
@@ -300,7 +301,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     # Build a note object for comment form
     @note = @project.notes.new(noteable: @merge_request)
     @notes = @merge_request.mr_and_commit_notes.nonawards.inc_author.fresh
-    @discussions = Note.discussions_from_notes(@notes)
+    @discussions = @notes.discussions
     @noteable = @merge_request
 
     # Get commits from repository
diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb
index 707a0d0e5c646a8294d01b7accd2706978d07ad4..4a57cd29a20365a39757140030d0fa713f37ad9c 100644
--- a/app/controllers/projects/notes_controller.rb
+++ b/app/controllers/projects/notes_controller.rb
@@ -96,7 +96,7 @@ class Projects::NotesController < Projects::ApplicationController
   end
 
   def note_to_discussion_html(note)
-    return unless note.for_diff_line?
+    return unless note.diff_note?
 
     if params[:view] == 'parallel'
       template = "projects/notes/_diff_notes_with_reply_parallel"
@@ -120,7 +120,7 @@ class Projects::NotesController < Projects::ApplicationController
   end
 
   def note_to_discussion_with_diff_html(note)
-    return unless note.for_diff_line?
+    return unless note.diff_note?
 
     render_to_string(
       "projects/notes/_discussion",
@@ -158,7 +158,7 @@ class Projects::NotesController < Projects::ApplicationController
   def note_params
     params.require(:note).permit(
       :note, :noteable, :noteable_id, :noteable_type, :project_id,
-      :attachment, :line_code, :commit_id
+      :attachment, :line_code, :commit_id, :type
     )
   end
 
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 352bff1938335734ba410866ad4089119be275b2..26eb15f49e41c88ce5ec11939cee650040188fe6 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -37,8 +37,8 @@ class RegistrationsController < Devise::RegistrationsController
     super
   end
 
-  def after_sign_up_path_for(_resource)
-    users_almost_there_path
+  def after_sign_up_path_for(user)
+    user.confirmed_at.present? ? dashboard_projects_path : users_almost_there_path
   end
 
   def after_inactive_sign_up_path_for(_resource)
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index f00f3f709e99c7e9d4fd792209f2aba989d20d8f..5849e00662b9a1a59bd65bbeeaa3903f99fe4f82 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -252,8 +252,8 @@ class IssuableFinder
       if filter_by_no_milestone?
         items = items.where(milestone_id: [-1, nil])
       elsif filter_by_upcoming_milestone?
-        upcoming = Milestone.where(project_id: projects).upcoming
-        items = items.joins(:milestone).where(milestones: { title: upcoming.try(:title) })
+        upcoming_ids = Milestone.upcoming_ids_by_projects(projects)
+        items = items.joins(:milestone).where(milestone_id: upcoming_ids)
       else
         items = items.joins(:milestone).where(milestones: { title: params[:milestone_title] })
 
diff --git a/app/finders/notes_finder.rb b/app/finders/notes_finder.rb
index fa4c635f55cfc589b78d01a38a120e0dbfae4cfc..c41be333537f875888989a01f5db10be45d19c02 100644
--- a/app/finders/notes_finder.rb
+++ b/app/finders/notes_finder.rb
@@ -10,7 +10,7 @@ class NotesFinder
     notes =
       case target_type
       when "commit"
-        project.notes.for_commit_id(target_id).not_inline
+        project.notes.for_commit_id(target_id).non_diff_notes
       when "issue"
         project.issues.find(target_id).notes.nonawards.inc_author
       when "merge_request"
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index 9f73edb45534e34577f5ec7c7dd11511dc55c5c9..5f311f3780a24c8ffd0606a115684cefef1d0cd8 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -55,22 +55,18 @@ module DiffHelper
     end
   end
 
-  def line_comments
-    @line_comments ||= @line_notes.select(&:active?).sort_by(&:created_at).group_by(&:line_code)
-  end
-
-  def organize_comments(type_left, type_right, line_code_left, line_code_right)
-    comments_left = comments_right = nil
+  def organize_comments(left, right)
+    notes_left = notes_right = nil
 
-    unless type_left.nil? && type_right == 'new'
-      comments_left = line_comments[line_code_left]
+    unless left[:type].nil? && right[:type] == 'new'
+      notes_left = @grouped_diff_notes[left[:line_code]]
     end
 
-    unless type_left.nil? && type_right.nil?
-      comments_right = line_comments[line_code_right]
+    unless left[:type].nil? && right[:type].nil?
+      notes_right = @grouped_diff_notes[right[:line_code]]
     end
 
-    [comments_left, comments_right]
+    [notes_left, notes_right]
   end
 
   def inline_diff_btn
@@ -96,8 +92,8 @@ module DiffHelper
     ].join(' ').html_safe
   end
 
-  def commit_for_diff(diff)
-    if diff.deleted_file
+  def commit_for_diff(diff_file)
+    if diff_file.deleted_file
       @base_commit || @commit.parent || @commit
     else
       @commit
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index 0bf328e7d19f71f232402aa01689d9b68f18256c..e14893817065f5640e5dcd866e3581fb4642287a 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -3,7 +3,7 @@ module EventsHelper
     author = event.author
 
     if author
-      link_to author.name, user_path(author.username), title: h(author.name)
+      link_to author.name, user_path(author.username), title: author.name
     else
       event.author_name
     end
@@ -57,11 +57,7 @@ module EventsHelper
       words << event.ref_name
       words << "at"
     elsif event.commented?
-      if event.note_commit?
-        words << event.note_short_commit_id
-      else
-        words << "##{truncate event.note_target_iid}"
-      end
+      words << event.note_target_reference
       words << "at"
     elsif event.milestone?
       words << "##{event.target_iid}" if event.target_iid
@@ -84,21 +80,12 @@ module EventsHelper
     elsif event.merge_request?
       namespace_project_merge_request_url(event.project.namespace,
                                           event.project, event.merge_request)
-    elsif event.note? && event.note_commit?
+    elsif event.note? && event.commit_note?
       namespace_project_commit_url(event.project.namespace, event.project,
                                    event.note_target)
     elsif event.note?
       if event.note_target
-        if event.note_commit?
-          namespace_project_commit_path(event.project.namespace, event.project,
-                                        event.note_commit_id,
-                                        anchor: dom_id(event.target))
-        elsif event.note_project_snippet?
-          namespace_project_snippet_path(event.project.namespace,
-                                         event.project, event.note_target)
-        else
-          event_note_target_path(event)
-        end
+        event_note_target_path(event)
       end
     elsif event.push?
       push_event_feed_url(event)
@@ -134,42 +121,30 @@ module EventsHelper
   end
 
   def event_note_target_path(event)
-    if event.note? && event.note_commit?
-      namespace_project_commit_path(event.project.namespace, event.project,
-                                    event.note_target)
+    if event.note? && event.commit_note?
+      namespace_project_commit_path(event.project.namespace,
+                                    event.project,
+                                    event.note_target,
+                                    anchor: dom_id(event.target))
+    elsif event.project_snippet_note?
+      namespace_project_snippet_path(event.project.namespace,
+                                     event.project,
+                                     event.note_target,
+                                     anchor: dom_id(event.target))
     else
       polymorphic_path([event.project.namespace.becomes(Namespace),
                         event.project, event.note_target],
-                       anchor: dom_id(event.target))
+                        anchor: dom_id(event.target))
     end
   end
 
   def event_note_title_html(event)
     if event.note_target
-      if event.note_commit?
-        link_to(
-          namespace_project_commit_path(event.project.namespace, event.project,
-                                        event.note_commit_id,
-                                        anchor: dom_id(event.target), title: h(event.target_title)),
-          class: "commit_short_id"
-        ) do
-          "#{event.note_target_type} #{event.note_short_commit_id}"
-        end
-      elsif event.note_project_snippet?
-        link_to(namespace_project_snippet_path(event.project.namespace,
-                                               event.project,
-                                               event.note_target), title: h(event.project.name)) do
-          "#{event.note_target_type} #{truncate event.note_target.to_reference}"
-        end
-      else
-        link_to event_note_target_path(event) do
-          "#{event.note_target_type} #{truncate event.note_target.to_reference}"
-        end
+      link_to(event_note_target_path(event), title: event.target_title, class: 'has-tooltip') do
+        "#{event.note_target_type} #{event.note_target_reference}"
       end
     else
-      content_tag :strong do
-        "(deleted)"
-      end
+      content_tag(:strong, '(deleted)')
     end
   end
 
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index 95072b5373fd21a4433d1d37b98cdbc57ec71544..b401c8385beeb2798f54222d89a890b7c7a92c55 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -1,7 +1,7 @@
 module NotesHelper
   # Helps to distinguish e.g. commit notes in mr notes list
   def note_for_main_target?(note)
-    (@noteable.class.name == note.noteable_type && !note.for_diff_line?)
+    @noteable.class.name == note.noteable_type && !note.diff_note?
   end
 
   def note_target_fields(note)
@@ -15,16 +15,6 @@ module NotesHelper
     note.editable? && can?(current_user, :admin_note, note)
   end
 
-  def link_to_commit_diff_line_note(note)
-    if note.for_commit_diff_line?
-      link_to(
-        "#{note.diff_file_name}:L#{note.diff_new_line}",
-        namespace_project_commit_path(@project.namespace, @project,
-                                      note.noteable, anchor: note.line_code)
-      )
-    end
-  end
-
   def noteable_json(noteable)
     {
       id: noteable.id,
@@ -35,7 +25,7 @@ module NotesHelper
   end
 
   def link_to_new_diff_note(line_code, line_type = nil)
-    discussion_id = Note.build_discussion_id(
+    discussion_id = LegacyDiffNote.build_discussion_id(
       @comments_target[:noteable_type],
       @comments_target[:noteable_id] || @comments_target[:commit_id],
       line_code
@@ -45,9 +35,10 @@ module NotesHelper
       noteable_type: @comments_target[:noteable_type],
       noteable_id:   @comments_target[:noteable_id],
       commit_id:     @comments_target[:commit_id],
+      line_type:     line_type,
       line_code:     line_code,
-      discussion_id: discussion_id,
-      line_type:     line_type
+      note_type:     LegacyDiffNote.name,
+      discussion_id: discussion_id
     }
 
     button_tag(class: 'btn add-diff-note js-add-diff-note-button',
@@ -57,18 +48,24 @@ module NotesHelper
     end
   end
 
-  def link_to_reply_diff(note, line_type = nil)
+  def link_to_reply_discussion(note, line_type = nil)
     return unless current_user
 
     data = {
       noteable_type: note.noteable_type,
       noteable_id:   note.noteable_id,
       commit_id:     note.commit_id,
-      line_code:     note.line_code,
       discussion_id: note.discussion_id,
       line_type:     line_type
     }
 
+    if note.diff_note?
+      data.merge!(
+        line_code: note.line_code,
+        note_type: LegacyDiffNote.name
+      )
+    end
+
     button_tag 'Reply...', class: 'btn btn-text-field js-discussion-reply-button',
                            data: data, title: 'Add a reply'
   end
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 1a10768655fb33bd8e1f5539146e491e500906e5..f5079f92444ced909ec9de1c14ec9a747d2b4575 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -120,7 +120,8 @@ class ApplicationSetting < ActiveRecord::Base
       recaptcha_enabled: false,
       akismet_enabled: false,
       repository_checks_enabled: true,
-      disabled_oauth_sign_in_sources: []
+      disabled_oauth_sign_in_sources: [],
+      send_user_confirmation_email: false
     )
   end
 
diff --git a/app/models/event.rb b/app/models/event.rb
index 17ee48b91a8bad512f976bf48774b251be64d160..716039fb54b9533477c5be3fd286124b2f28086e 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -80,7 +80,7 @@ class Event < ActiveRecord::Base
   end
 
   def target_title
-    target.title if target && target.respond_to?(:title)
+    target.try(:title)
   end
 
   def created?
@@ -266,28 +266,20 @@ class Event < ActiveRecord::Base
     branch? && project.default_branch != branch_name
   end
 
-  def note_commit_id
-    target.commit_id
-  end
-
   def target_iid
     target.respond_to?(:iid) ? target.iid : target_id
   end
 
-  def note_short_commit_id
-    Commit.truncate_sha(note_commit_id)
-  end
-
-  def note_commit?
-    target.noteable_type == "Commit"
+  def commit_note?
+    target.for_commit?
   end
 
   def issue_note?
-    note? && target && target.noteable_type == "Issue"
+    note? && target && target.for_issue?
   end
 
-  def note_project_snippet?
-    target.noteable_type == "Snippet"
+  def project_snippet_note?
+    target.for_snippet?
   end
 
   def note_target
@@ -295,19 +287,22 @@ class Event < ActiveRecord::Base
   end
 
   def note_target_id
-    if note_commit?
+    if commit_note?
       target.commit_id
     else
       target.noteable_id.to_s
     end
   end
 
-  def note_target_iid
-    if note_target.respond_to?(:iid)
-      note_target.iid
+  def note_target_reference
+    return unless note_target
+
+    # Commit#to_reference returns the full SHA, but we want the short one here
+    if commit_note?
+      note_target.short_id
     else
-      note_target_id
-    end.to_s
+      note_target.to_reference
+    end
   end
 
   def note_target_type
diff --git a/app/models/legacy_diff_note.rb b/app/models/legacy_diff_note.rb
new file mode 100644
index 0000000000000000000000000000000000000000..bbefc911b29ca4a5f65e37e19d5be5b6481af311
--- /dev/null
+++ b/app/models/legacy_diff_note.rb
@@ -0,0 +1,157 @@
+class LegacyDiffNote < Note
+  serialize :st_diff
+
+  validates :line_code, presence: true, line_code: true
+
+  before_create :set_diff
+
+  class << self
+    def build_discussion_id(noteable_type, noteable_id, line_code, active = true)
+      [super(noteable_type, noteable_id), line_code, active].join("-")
+    end
+  end
+
+  def diff_note?
+    true
+  end
+
+  def legacy_diff_note?
+    true
+  end
+
+  def discussion_id
+    @discussion_id ||= self.class.build_discussion_id(noteable_type, noteable_id || commit_id, line_code, active?)
+  end
+
+  def diff_file_hash
+    line_code.split('_')[0] if line_code
+  end
+
+  def diff_old_line
+    line_code.split('_')[1].to_i if line_code
+  end
+
+  def diff_new_line
+    line_code.split('_')[2].to_i if line_code
+  end
+
+  def diff
+    @diff ||= Gitlab::Git::Diff.new(st_diff) if st_diff.respond_to?(:map)
+  end
+
+  def diff_file_path
+    diff.new_path.presence || diff.old_path
+  end
+
+  def diff_lines
+    @diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.each_line)
+  end
+
+  def diff_line
+    @diff_line ||= diff_lines.find { |line| generate_line_code(line) == self.line_code }
+  end
+
+  def diff_line_text
+    diff_line.try(:text)
+  end
+
+  def diff_line_type
+    diff_line.try(:type)
+  end
+
+  def highlighted_diff_lines
+    Gitlab::Diff::Highlight.new(diff_lines).highlight
+  end
+
+  def truncated_diff_lines
+    max_number_of_lines = 16
+    prev_match_line = nil
+    prev_lines = []
+
+    highlighted_diff_lines.each do |line|
+      if line.type == "match"
+        prev_lines.clear
+        prev_match_line = line
+      else
+        prev_lines << line
+
+        break if generate_line_code(line) == self.line_code
+
+        prev_lines.shift if prev_lines.length >= max_number_of_lines
+      end
+    end
+
+    prev_lines
+  end
+
+  # Check if this note is part of an "active" discussion
+  #
+  # This will always return true for anything except MergeRequest noteables,
+  # which have special logic.
+  #
+  # If the note's current diff cannot be matched in the MergeRequest's current
+  # diff, it's considered inactive.
+  def active?
+    return @active if defined?(@active)
+    return true if for_commit?
+    return true unless self.diff
+    return false unless noteable
+
+    noteable_diff = find_noteable_diff
+
+    if noteable_diff
+      parsed_lines = Gitlab::Diff::Parser.new.parse(noteable_diff.diff.each_line)
+
+      @active = parsed_lines.any? { |line_obj| line_obj.text == diff_line_text }
+    else
+      @active = false
+    end
+
+    @active
+  end
+
+  private
+
+  def find_diff
+    return nil unless noteable
+    return @diff if defined?(@diff)
+
+    @diff = noteable.diffs(Commit.max_diff_options).find do |d|
+      d.new_path && Digest::SHA1.hexdigest(d.new_path) == diff_file_hash
+    end
+  end
+
+  def set_diff
+    # First lets find notes with same diff
+    # before iterating over all mr diffs
+    diff = diff_for_line_code unless for_merge_request?
+    diff ||= find_diff
+
+    self.st_diff = diff.to_hash if diff
+  end
+
+  def diff_for_line_code
+    attributes = {
+      noteable_type: noteable_type,
+      line_code: line_code
+    }
+
+    if for_commit?
+      attributes[:commit_id] = commit_id
+    else
+      attributes[:noteable_id] = noteable_id
+    end
+
+    self.class.where(attributes).last.try(:diff)
+  end
+
+  def generate_line_code(line)
+    Gitlab::Diff::LineCode.generate(diff_file_path, line.new_pos, line.old_pos)
+  end
+
+  # Find the diff on noteable that matches our own
+  def find_noteable_diff
+    diffs = noteable.diffs(Commit.max_diff_options)
+    diffs.find { |d| d.new_path == self.diff.new_path }
+  end
+end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 5c5e6007aa0a746355ecf98b1e80d4e88a67f7d1..45ddcf6812a9dd9f261336c8d5201bb9323089df 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -26,6 +26,10 @@ class MergeRequest < ActiveRecord::Base
   # when creating new merge request
   attr_accessor :can_be_created, :compare_commits, :compare
 
+  # Temporary fields to store target_sha, and base_sha to
+  # compare when importing pull requests from GitHub
+  attr_accessor :base_target_sha, :head_source_sha
+
   state_machine :state, initial: :opened do
     event :close do
       transition [:reopened, :opened] => :closed
@@ -490,10 +494,14 @@ class MergeRequest < ActiveRecord::Base
   end
 
   def target_sha
-    @target_sha ||= target_project.repository.commit(target_branch).try(:sha)
+    return @base_target_sha if defined?(@base_target_sha)
+
+    target_project.repository.commit(target_branch).try(:sha)
   end
 
   def source_sha
+    return @head_source_sha if defined?(@head_source_sha)
+
     last_commit.try(:sha) || source_tip.try(:sha)
   end
 
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index eb42c07b9b92fe7f639eeac341092e4044f82570..6ad8fc3f0342b0fcd63cc264aead05268ed818c2 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -6,7 +6,7 @@ class MergeRequestDiff < ActiveRecord::Base
 
   belongs_to :merge_request
 
-  delegate :target_branch, :source_branch, to: :merge_request, prefix: nil
+  delegate :head_source_sha, :target_branch, :source_branch, to: :merge_request, prefix: nil
 
   state_machine :state, initial: :empty do
     state :collected
@@ -38,8 +38,8 @@ class MergeRequestDiff < ActiveRecord::Base
       @diffs_no_whitespace ||= begin
         compare = Gitlab::Git::Compare.new(
           self.repository.raw_repository,
-          self.target_branch,
-          self.source_sha,
+          self.base,
+          self.head,
         )
         compare.diffs(options)
       end
@@ -144,7 +144,7 @@ class MergeRequestDiff < ActiveRecord::Base
 
     self.st_diffs = new_diffs
 
-    self.base_commit_sha = self.repository.merge_base(self.source_sha, self.target_branch)
+    self.base_commit_sha = self.repository.merge_base(self.head, self.base)
 
     self.save
   end
@@ -160,10 +160,24 @@ class MergeRequestDiff < ActiveRecord::Base
   end
 
   def source_sha
+    return head_source_sha if head_source_sha.present?
+
     source_commit = merge_request.source_project.commit(source_branch)
     source_commit.try(:sha)
   end
 
+  def target_sha
+    merge_request.target_sha
+  end
+
+  def base
+    self.target_sha || self.target_branch
+  end
+
+  def head
+    self.source_sha
+  end
+
   def compare
     @compare ||=
       begin
@@ -172,8 +186,8 @@ class MergeRequestDiff < ActiveRecord::Base
 
         Gitlab::Git::Compare.new(
           self.repository.raw_repository,
-          self.target_branch,
-          self.source_sha
+          self.base,
+          self.head
         )
       end
   end
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index e4fdd23badb5d94f71e77769d8e786a77b411a37..fe9a281f3661d4719c2162fd7e79c08c36ee2d87 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -67,8 +67,18 @@ class Milestone < ActiveRecord::Base
     @link_reference_pattern ||= super("milestones", /(?<milestone>\d+)/)
   end
 
-  def self.upcoming
-    self.where('due_date > ?', Time.now).reorder(due_date: :asc).first
+  def self.upcoming_ids_by_projects(projects)
+    rel = unscoped.of_projects(projects).active.where('due_date > ?', Time.now)
+
+    if Gitlab::Database.postgresql?
+      rel.order(:project_id, :due_date).select('DISTINCT ON (project_id) id')
+    else
+      rel.
+        group(:project_id).
+        having('due_date = MIN(due_date)').
+        pluck(:id, :project_id, :due_date).
+        map(&:first)
+    end
   end
 
   def to_reference(from_project = nil)
diff --git a/app/models/note.rb b/app/models/note.rb
index f26aa1bf63f79f7b6079a4bfc9dbe59d4fb132ec..55b98557244aaab7fdc5534f01c60bdb09b57ed6 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -1,6 +1,5 @@
-require 'carrierwave/orm/activerecord'
-
 class Note < ActiveRecord::Base
+  extend ActiveModel::Naming
   include Gitlab::CurrentSettings
   include Participable
   include Mentionable
@@ -20,14 +19,13 @@ class Note < ActiveRecord::Base
   delegate :gfm_reference, :local_reference, to: :noteable
   delegate :name, to: :project, prefix: true
   delegate :name, :email, to: :author, prefix: true
+  delegate :title, to: :noteable, allow_nil: true
 
   before_validation :set_award!
-  before_validation :clear_blank_line_code!
 
   validates :note, :project, presence: true
   validates :note, uniqueness: { scope: [:author, :noteable_type, :noteable_id] }, if: ->(n) { n.is_award }
   validates :note, inclusion: { in: Emoji.emojis_names }, if: ->(n) { n.is_award }
-  validates :line_code, line_code: true, allow_blank: true
   # Attachments are deprecated and are handled by Markdown uploader
   validates :attachment, file_size: { maximum: :max_attachment_size }
 
@@ -41,8 +39,6 @@ class Note < ActiveRecord::Base
   scope :awards, ->{ where(is_award: true) }
   scope :nonawards, ->{ where(is_award: false) }
   scope :for_commit_id, ->(commit_id) { where(noteable_type: "Commit", commit_id: commit_id) }
-  scope :inline, ->{ where("line_code IS NOT NULL") }
-  scope :not_inline, ->{ where(line_code: nil) }
   scope :system, ->{ where(system: true) }
   scope :user, ->{ where(system: false) }
   scope :common, ->{ where(noteable_type: ["", nil]) }
@@ -50,38 +46,31 @@ class Note < ActiveRecord::Base
   scope :inc_author_project, ->{ includes(:project, :author) }
   scope :inc_author, ->{ includes(:author) }
 
+  scope :legacy_diff_notes, ->{ where(type: 'LegacyDiffNote') }
+  scope :non_diff_notes, ->{ where(type: ['Note', nil]) }
+
   scope :with_associations, -> do
     includes(:author, :noteable, :updated_by,
              project: [:project_members, { group: [:group_members] }])
   end
 
-  serialize :st_diff
-  before_create :set_diff, if: ->(n) { n.line_code.present? }
+  before_validation :clear_blank_line_code!
 
   class << self
-    def discussions_from_notes(notes)
-      discussion_ids = []
-      discussions = []
-
-      notes.each do |note|
-        next if discussion_ids.include?(note.discussion_id)
-
-        # don't group notes for the main target
-        if !note.for_diff_line? && note.for_merge_request?
-          discussions << [note]
-        else
-          discussions << notes.select do |other_note|
-            note.discussion_id == other_note.discussion_id
-          end
-          discussion_ids << note.discussion_id
-        end
-      end
+    def model_name
+      ActiveModel::Name.new(self, nil, 'note')
+    end
+
+    def build_discussion_id(noteable_type, noteable_id)
+      [:discussion, noteable_type.try(:underscore), noteable_id].join("-")
+    end
 
-      discussions
+    def discussions
+      all.group_by(&:discussion_id).values
     end
 
-    def build_discussion_id(type, id, line_code)
-      [:discussion, type.try(:underscore), id, line_code].join("-").to_sym
+    def grouped_diff_notes
+      legacy_diff_notes.select(&:active?).sort_by(&:created_at).group_by(&:line_code)
     end
 
     # Searches for notes matching the given query.
@@ -116,167 +105,39 @@ class Note < ActiveRecord::Base
     system && SystemNoteService.cross_reference?(note)
   end
 
-  def max_attachment_size
-    current_application_settings.max_attachment_size.megabytes.to_i
-  end
-
-  def find_diff
-    return nil unless noteable
-    return @diff if defined?(@diff)
-
-    # Don't use ||= because nil is a valid value for @diff
-    @diff = noteable.diffs(Commit.max_diff_options).find do |d|
-      Digest::SHA1.hexdigest(d.new_path) == diff_file_index if d.new_path
-    end
-  end
-
-  def hook_attrs
-    attributes
+  def diff_note?
+    false
   end
 
-  def set_diff
-    # First lets find notes with same diff
-    # before iterating over all mr diffs
-    diff = diff_for_line_code unless for_merge_request?
-    diff ||= find_diff
-
-    self.st_diff = diff.to_hash if diff
+  def legacy_diff_note?
+    false
   end
 
-  def diff
-    @diff ||= Gitlab::Git::Diff.new(st_diff) if st_diff.respond_to?(:map)
-  end
-
-  def diff_for_line_code
-    Note.where(noteable_id: noteable_id, noteable_type: noteable_type, line_code: line_code).last.try(:diff)
-  end
-
-  # Check if this note is part of an "active" discussion
-  #
-  # This will always return true for anything except MergeRequest noteables,
-  # which have special logic.
-  #
-  # If the note's current diff cannot be matched in the MergeRequest's current
-  # diff, it's considered inactive.
   def active?
-    return true unless self.diff
-    return false unless noteable
-    return @active if defined?(@active)
-
-    noteable_diff = find_noteable_diff
-
-    if noteable_diff
-      parsed_lines = Gitlab::Diff::Parser.new.parse(noteable_diff.diff.each_line)
-
-      @active = parsed_lines.any? { |line_obj| line_obj.text == diff_line }
-    else
-      @active = false
-    end
-
-    @active
-  end
-
-  def diff_file_index
-    line_code.split('_')[0] if line_code
-  end
-
-  def diff_file_name
-    diff.new_path if diff
+    true
   end
 
-  def file_path
-    if diff.new_path.present?
-      diff.new_path
-    elsif diff.old_path.present?
-      diff.old_path
-    end
-  end
-
-  def diff_old_line
-    line_code.split('_')[1].to_i if line_code
-  end
-
-  def diff_new_line
-    line_code.split('_')[2].to_i if line_code
-  end
-
-  def generate_line_code(line)
-    Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
-  end
-
-  def diff_line
-    return @diff_line if @diff_line
-
-    if diff
-      diff_lines.each do |line|
-        if generate_line_code(line) == self.line_code
-          @diff_line = line.text
-        end
-      end
-    end
-
-    @diff_line
-  end
-
-  def diff_line_type
-    return @diff_line_type if @diff_line_type
-
-    if diff
-      diff_lines.each do |line|
-        if generate_line_code(line) == self.line_code
-          @diff_line_type = line.type
-        end
-      end
-    end
-
-    @diff_line_type
-  end
-
-  def truncated_diff_lines
-    max_number_of_lines = 16
-    prev_match_line = nil
-    prev_lines = []
-
-    highlighted_diff_lines.each do |line|
-      if line.type == "match"
-        prev_lines.clear
-        prev_match_line = line
+  def discussion_id
+    @discussion_id ||=
+      if for_merge_request?
+        [:discussion, :note, id].join("-")
       else
-        prev_lines << line
-
-        break if generate_line_code(line) == self.line_code
-
-        prev_lines.shift if prev_lines.length >= max_number_of_lines
+        self.class.build_discussion_id(noteable_type, noteable_id || commit_id)
       end
-    end
-
-    prev_lines
-  end
-
-  def diff_lines
-    @diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.each_line)
   end
 
-  def highlighted_diff_lines
-    Gitlab::Diff::Highlight.new(diff_lines).highlight
+  def max_attachment_size
+    current_application_settings.max_attachment_size.megabytes.to_i
   end
 
-  def discussion_id
-    @discussion_id ||= Note.build_discussion_id(noteable_type, noteable_id || commit_id, line_code)
+  def hook_attrs
+    attributes
   end
 
   def for_commit?
     noteable_type == "Commit"
   end
 
-  def for_commit_diff_line?
-    for_commit? && for_diff_line?
-  end
-
-  def for_diff_line?
-    line_code.present?
-  end
-
   def for_issue?
     noteable_type == "Issue"
   end
@@ -285,10 +146,6 @@ class Note < ActiveRecord::Base
     noteable_type == "MergeRequest"
   end
 
-  def for_merge_request_diff_line?
-    for_merge_request? && for_diff_line?
-  end
-
   def for_snippet?
     noteable_type == "Snippet"
   end
@@ -361,14 +218,8 @@ class Note < ActiveRecord::Base
     self.line_code = nil if self.line_code.blank?
   end
 
-  # Find the diff on noteable that matches our own
-  def find_noteable_diff
-    diffs = noteable.diffs(Commit.max_diff_options)
-    diffs.find { |d| d.new_path == self.diff.new_path }
-  end
-
   def awards_supported?
-    (for_issue? || for_merge_request?) && !for_diff_line?
+    (for_issue? || for_merge_request?) && !diff_note?
   end
 
   def contains_emoji_only?
diff --git a/app/models/project.rb b/app/models/project.rb
index a3eb7d83e49d0cd6dc3bf05d9aee4bac13e68077..8e80a6b5c01a936efc5210b57f1841cd65187956 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -50,6 +50,8 @@ class Project < ActiveRecord::Base
   attr_accessor :new_default_branch
   attr_accessor :old_path_with_namespace
 
+  alias_attribute :title, :name
+
   # Relations
   belongs_to :creator, foreign_key: 'creator_id', class_name: 'User'
   belongs_to :group, -> { where(type: Group) }, foreign_key: 'namespace_id'
diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb
index 060ed9b44ecd8db68fa4538ca57b2bd0ae64be21..339fb0b9f9d6d9622704456bbd01b3f75df4e1c8 100644
--- a/app/models/project_wiki.rb
+++ b/app/models/project_wiki.rb
@@ -40,7 +40,7 @@ class ProjectWiki
   end
 
   def wiki_base_path
-    ["/", @project.path_with_namespace, "/wikis"].join('')
+    [Gitlab.config.gitlab.relative_url_root, "/", @project.path_with_namespace, "/wikis"].join('')
   end
 
   # Returns the Gollum::Wiki object.
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 0eff74320f39cc2087bf551230513bbed11f92c9..3716ea6ad6c95c17910c1f283ff90359e67d203d 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -195,6 +195,10 @@ class Repository
     cache.fetch(:branch_names) { branches.map(&:name) }
   end
 
+  def branch_exists?(branch_name)
+    branch_names.include?(branch_name)
+  end
+
   def tag_names
     cache.fetch(:tag_names) { raw_repository.tag_names }
   end
diff --git a/app/models/user.rb b/app/models/user.rb
index 489bff3fa4a907963c2efe8ebad5ee5da12324e8..368a3f3cfbae5a6d9dffd8f265bf88272b13a110 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -112,6 +112,7 @@ class User < ActiveRecord::Base
   before_save :ensure_external_user_rights
   after_save :ensure_namespace_correct
   after_initialize :set_projects_limit
+  before_create :check_confirmation_email
   after_create :post_create_hook
   after_destroy :post_destroy_hook
 
@@ -307,6 +308,10 @@ class User < ActiveRecord::Base
     @reset_token
   end
 
+  def check_confirmation_email
+    skip_confirmation! unless current_application_settings.send_user_confirmation_email
+  end
+
   def recently_sent_password_reset?
     reset_password_sent_at.present? && reset_password_sent_at >= 1.minute.ago
   end
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index f7c799c968f5e64b29df22b9ed1bb3f86745cf3d..df286852b97df2f650ce39fc804da6908f94b4a3 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -103,6 +103,12 @@
           = f.label :signup_enabled do
             = f.check_box :signup_enabled
             Sign-up enabled
+    .form-group
+      .col-sm-offset-2.col-sm-10
+        .checkbox
+          = f.label :send_user_confirmation_email do
+            = f.check_box :send_user_confirmation_email
+            Send confirmation email on sign-up
     .form-group
       .col-sm-offset-2.col-sm-10
         .checkbox
diff --git a/app/views/events/event/_common.html.haml b/app/views/events/event/_common.html.haml
index c994e3b997de6b85e747f6872837e2e05995bb1c..f9f623cc031a7c092b26f3efbfcebe7d55f38b71 100644
--- a/app/views/events/event/_common.html.haml
+++ b/app/views/events/event/_common.html.haml
@@ -4,7 +4,7 @@
     = event_action_name(event)
 
   - if event.target
-    %strong= link_to event.target.reference_link_text, [event.project.namespace.becomes(Namespace), event.project, event.target]
+    %strong= link_to event.target.reference_link_text, [event.project.namespace.becomes(Namespace), event.project, event.target], title: event.target_title
 
   = event_preposition(event)
 
diff --git a/app/views/notify/note_merge_request_email.html.haml b/app/views/notify/note_merge_request_email.html.haml
index 65f0e4c4068fbb3fbcdb3d0f358b1a1c9064698e..a3643a00cfe7310e99d11a9073f386bb07fe4480 100644
--- a/app/views/notify/note_merge_request_email.html.haml
+++ b/app/views/notify/note_merge_request_email.html.haml
@@ -1,7 +1,7 @@
-- if @note.diff_file_name
+- if @note.legacy_diff_note?
   %p.details
     New comment on diff for
-    = link_to @note.diff_file_name, @target_url
+    = link_to @note.diff_file_path, @target_url
     \:
 
 = render 'note_message'
diff --git a/app/views/projects/diffs/_line.html.haml b/app/views/projects/diffs/_line.html.haml
index 107097ad9635b658498a5fff0ff072d0d24172ce..f1577e8a47b4cb85363e11a7df53e477f14fe404 100644
--- a/app/views/projects/diffs/_line.html.haml
+++ b/app/views/projects/diffs/_line.html.haml
@@ -15,7 +15,7 @@
         = link_text
       - else
         = link_to "", "##{line_code}", id: line_code, data: { linenumber: link_text }
-      - if @comments_allowed && can?(current_user, :create_note, @project)
+      - if !@diff_notes_disabled && can?(current_user, :create_note, @project)
         = link_to_new_diff_note(line_code)
     %td.new_line.diff-line-num{ class: type, data: { linenumber: line.new_pos } }
       - link_text = type == "old" ? "&nbsp;".html_safe : line.new_pos
diff --git a/app/views/projects/diffs/_parallel_view.html.haml b/app/views/projects/diffs/_parallel_view.html.haml
index 81948513e43c5cc2d93177677428d6eeeb244d32..4ecc9528bd25039c56c80241b1e61121ef9083de 100644
--- a/app/views/projects/diffs/_parallel_view.html.haml
+++ b/app/views/projects/diffs/_parallel_view.html.haml
@@ -16,7 +16,7 @@
         - else
           %td.old_line.diff-line-num{id: left[:line_code], class: "#{left[:type]} #{'empty-cell' if !left[:number]}"}
             = link_to raw(left[:number]), "##{left[:line_code]}", id: left[:line_code]
-            - if @comments_allowed && can?(current_user, :create_note, @project)
+            - if !@diff_notes_disabled && can?(current_user, :create_note, @project)
               = link_to_new_diff_note(left[:line_code], 'old')
           %td.line_content{class: "parallel noteable_line #{left[:type]} #{left[:line_code]} #{'empty-cell' if left[:text].empty?}", data: { line_code: left[:line_code] }}= diff_line_content(left[:text])
 
@@ -29,14 +29,14 @@
 
           %td.new_line.diff-line-num{id: new_line_code, class: "#{new_line_class} #{'empty-cell' if !right[:number]}", data: { linenumber: right[:number] }}
             = link_to raw(right[:number]), "##{new_line_code}", id: new_line_code
-            - if @comments_allowed && can?(current_user, :create_note, @project)
-              = link_to_new_diff_note(right[:line_code], 'new')
+            - if !@diff_notes_disabled && can?(current_user, :create_note, @project)
+              = link_to_new_diff_note(new_line_code, 'new')
           %td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code} #{'empty-cell' if right[:text].empty?}", data: { line_code: new_line_code }}= diff_line_content(right[:text])
 
-      - if @reply_allowed
-        - comments_left, comments_right = organize_comments(left[:type], right[:type], left[:line_code], right[:line_code])
-        - if comments_left.present? || comments_right.present?
-          = render "projects/notes/diff_notes_with_reply_parallel", notes_left: comments_left, notes_right: comments_right
+      - unless @diff_notes_disabled
+        - notes_left, notes_right = organize_comments(left, right)
+        - if notes_left.present? || notes_right.present?
+          = render "projects/notes/diff_notes_with_reply_parallel", notes_left: notes_left, notes_right: notes_right
 
 - if diff_file.diff.diff.blank? && diff_file.mode_changed?
   .file-mode-changed
diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml
index e7169d7b599f74e4f8e3c0bacb34b8c10477ce0b..068593a7dd152de50bf892abb4c06c43985c691e 100644
--- a/app/views/projects/diffs/_text_file.html.haml
+++ b/app/views/projects/diffs/_text_file.html.haml
@@ -6,16 +6,15 @@
 %table.text-file.code.js-syntax-highlight{ class: too_big ? 'hide' : '' }
 
   - last_line = 0
-  - raw_diff_lines = diff_file.diff_lines.to_a
   - diff_file.highlighted_diff_lines.each_with_index do |line, index|
     - line_code = generate_line_code(diff_file.file_path, line)
     - last_line = line.new_pos
     = render "projects/diffs/line", {line: line, diff_file: diff_file, line_code: line_code}
 
-    - if @reply_allowed
-      - comments = @line_notes.select { |n| n.line_code == line_code && n.active? }.sort_by(&:created_at)
-      - unless comments.empty?
-        = render "projects/notes/diff_notes_with_reply", notes: comments, line: raw_diff_lines[index].text
+    - unless @diff_notes_disabled
+      - diff_notes = @grouped_diff_notes[line_code]
+      - if diff_notes
+        = render "projects/notes/diff_notes_with_reply", notes: diff_notes
 
   - if last_line > 0
     = render "projects/diffs/match_line", { line: "",
diff --git a/app/views/projects/notes/_commit_discussion.html.haml b/app/views/projects/notes/_commit_discussion.html.haml
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/app/views/projects/notes/_diff_notes_with_reply.html.haml b/app/views/projects/notes/_diff_notes_with_reply.html.haml
index 39be072855ae014157db8f6ab1c038e2e2782088..8144c1ba49ece2671e9340e785cfb1074c8e00eb 100644
--- a/app/views/projects/notes/_diff_notes_with_reply.html.haml
+++ b/app/views/projects/notes/_diff_notes_with_reply.html.haml
@@ -1,10 +1,8 @@
-- note = notes.first # example note
--# Check if line want not changed since comment was left
-- if !defined?(line) || line == note.diff_line
-  %tr.notes_holder
-    %td.notes_line{ colspan: 2 }
-    %td.notes_content
-      %ul.notes{ data: { discussion_id: note.discussion_id } }
-        = render notes
-      .discussion-reply-holder
-        = link_to_reply_diff(note)
+- note = notes.first
+%tr.notes_holder
+  %td.notes_line{ colspan: 2 }
+  %td.notes_content
+    %ul.notes{ data: { discussion_id: note.discussion_id } }
+      = render partial: "projects/notes/note", collection: notes, as: :note
+    .discussion-reply-holder
+      = link_to_reply_discussion(note)
diff --git a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml
index f8aa5e2fa7dfcf830194479e2d3d69cc7230f41e..45986b0d1e8e70aed7ce1a9d2c811f0105ccd4a0 100644
--- a/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml
+++ b/app/views/projects/notes/_diff_notes_with_reply_parallel.html.haml
@@ -1,27 +1,27 @@
-- note1 = notes_left.present? ? notes_left.first : nil
-- note2 = notes_right.present? ? notes_right.first : nil
+- note_left = notes_left.present? ? notes_left.first : nil
+- note_right = notes_right.present? ? notes_right.first : nil
 
 %tr.notes_holder
-  - if note1
+  - if note_left
     %td.notes_line.old
     %td.notes_content.parallel.old
-      %ul.notes{ data: { discussion_id: note1.discussion_id } }
-        = render notes_left
+      %ul.notes{ data: { discussion_id: note_left.discussion_id } }
+        = render partial: "projects/notes/note", collection: notes_left, as: :note
 
       .discussion-reply-holder
-        = link_to_reply_diff(note1, 'old')
+        = link_to_reply_discussion(note_left, 'old')
   - else
     %td.notes_line.old= ""
     %td.notes_content.parallel.old= ""
 
-  - if note2
+  - if note_right
     %td.notes_line.new
     %td.notes_content.parallel.new
-      %ul.notes{ data: { discussion_id: note2.discussion_id } }
-        = render notes_right
+      %ul.notes{ data: { discussion_id: note_right.discussion_id } }
+        = render partial: "projects/notes/note", collection: notes_right, as: :note
 
       .discussion-reply-holder
-        = link_to_reply_diff(note2, 'new')
+        = link_to_reply_discussion(note_right, 'new')
   - else
     %td.notes_line.new= ""
     %td.notes_content.parallel.new= ""
diff --git a/app/views/projects/notes/_discussion.html.haml b/app/views/projects/notes/_discussion.html.haml
index 572b00a38c76a73a02f234644090015984740114..7869d6413d8d877d93b2776e263c452b5e5e84e0 100644
--- a/app/views/projects/notes/_discussion.html.haml
+++ b/app/views/projects/notes/_discussion.html.haml
@@ -1,13 +1,46 @@
 - note = discussion_notes.first
+- expanded = !note.diff_note? || note.active?
 %li.note.note-discussion.timeline-entry
   .timeline-entry-inner
     .timeline-icon
       = link_to user_path(note.author) do
-        = image_tag avatar_icon(note.author_email), class: "avatar s40"
+        = image_tag avatar_icon(note.author), class: "avatar s40"
     .timeline-content
-      - if note.for_merge_request?
-        - (active_notes, outdated_notes) = discussion_notes.partition(&:active?)
-        = render "projects/notes/discussions/active", discussion_notes: active_notes if active_notes.length > 0
-        = render "projects/notes/discussions/outdated", discussion_notes: outdated_notes if outdated_notes.length > 0
-      - else
-        = render "projects/notes/discussions/commit", discussion_notes: discussion_notes
+      .discussion.js-toggle-container{ class: note.discussion_id }
+        .discussion-header
+          = link_to_member(@project, note.author, avatar: false)
+
+          .inline.discussion-headline-light
+            = note.author.to_reference
+            started a discussion on
+
+            - if note.for_commit?
+              - commit = note.noteable
+              - if commit
+                commit
+                = link_to commit.short_id, namespace_project_commit_path(note.project.namespace, note.project, note.noteable, anchor: note.line_code), class: 'monospace'
+              - else
+                a deleted commit
+            - else
+              - if note.active?
+                = link_to diffs_namespace_project_merge_request_path(note.project.namespace, note.project, note.noteable, anchor: note.line_code) do
+                  the diff
+              - else
+                an outdated diff
+
+            = time_ago_with_tooltip(note.created_at, placement: "bottom", html_class: "note-created-ago")
+
+          .discussion-actions
+            = link_to "#", class: "note-action-button discussion-toggle-button js-toggle-button" do
+              - if expanded
+                = icon("chevron-up")
+              - else
+                = icon("chevron-down")
+
+              Toggle discussion
+
+        .discussion-body.js-toggle-content{ class: ("hide" unless expanded) }
+          - if note.diff_note?
+            = render "projects/notes/discussions/diff_with_notes", discussion_notes: discussion_notes
+          - else
+            = render "projects/notes/discussions/notes", discussion_notes: discussion_notes
diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml
index d0ac380f216c41ea509208bc8c3822c7876c5825..67ed38a7b22c4d6cbeba8c531d02ed2116803e66 100644
--- a/app/views/projects/notes/_form.html.haml
+++ b/app/views/projects/notes/_form.html.haml
@@ -6,6 +6,7 @@
   = f.hidden_field :line_code
   = f.hidden_field :noteable_id
   = f.hidden_field :noteable_type
+  = f.hidden_field :type
 
   = render layout: 'projects/md_preview', locals: { preview_class: "md-preview", referenced_users: true } do
     = render 'projects/zen', f: f, attr: :note, classes: 'note-textarea js-note-text', placeholder: "Write a comment or drag your files here..."
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index aeb7c1d5ee43df0ec6a75360f1b030778db8cca9..9fbc9a45549125d86e0fc4c4daee57f6c0ed8669 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -1,5 +1,8 @@
+- return unless note.author
+- return if note.cross_reference_not_visible_for?(current_user)
+
 - note_editable = note_editable?(note)
-%li.timeline-entry{ id: dom_id(note), class: [dom_class(note), "note-row-#{note.id}", ('system-note' if note.system)], data: {author_id: note.author.id, editable: note_editable} }
+%li.timeline-entry{ id: dom_id(note), class: ["note", "note-row-#{note.id}", ('system-note' if note.system)], data: {author_id: note.author.id, editable: note_editable} }
   .timeline-entry-inner
     .timeline-icon
       %a{href: user_path(note.author)}
@@ -8,8 +11,8 @@
       .note-header
         = link_to_member(note.project, note.author, avatar: false)
         .inline.note-headline-light
-          = "#{note.author.to_reference}"
-          - if !note.system
+          = note.author.to_reference
+          - unless note.system
             commented
           %a{ href: "##{dom_id(note)}" }
             = time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago')
diff --git a/app/views/projects/notes/_notes.html.haml b/app/views/projects/notes/_notes.html.haml
index 62db86fb18171cd335b585f030e46ac361361c7e..ebf7e8a9cb344836a85e76a5a6f436b814771907 100644
--- a/app/views/projects/notes/_notes.html.haml
+++ b/app/views/projects/notes/_notes.html.haml
@@ -2,14 +2,9 @@
   - @discussions.each do |discussion_notes|
     - note = discussion_notes.first
     - if note_for_main_target?(note)
-      - next if note.cross_reference_not_visible_for?(current_user)
-
-      = render discussion_notes
+      = render partial: "projects/notes/note", object: note, as: :note
     - else
       = render 'projects/notes/discussion', discussion_notes: discussion_notes
 - else
   - @notes.each do |note|
-    - next unless note.author
-    - next if note.cross_reference_not_visible_for?(current_user)
-
-    = render note
+    = render partial: "projects/notes/note", object: note, as: :note
diff --git a/app/views/projects/notes/discussions/_active.html.haml b/app/views/projects/notes/discussions/_active.html.haml
deleted file mode 100644
index 0ea8862a684d13b3f021cdd06a3c51b45f236b1b..0000000000000000000000000000000000000000
--- a/app/views/projects/notes/discussions/_active.html.haml
+++ /dev/null
@@ -1,16 +0,0 @@
-- note = discussion_notes.first
-.discussion.js-toggle-container{ class: note.discussion_id }
-  .discussion-header
-    = link_to_member(@project, note.author, avatar: false)
-    .inline.discussion-headline-light
-      = "#{note.author.to_reference} started a discussion"
-      = link_to diffs_namespace_project_merge_request_path(note.project.namespace, note.project, note.noteable, anchor: note.line_code) do
-        on the diff
-      = time_ago_with_tooltip(note.created_at, placement: "bottom", html_class: "discussion_updated_ago")
-    .discussion-actions
-      = link_to "#", class: "discussion-action-button discussion-toggle-button js-toggle-button" do
-        %i.fa.fa-chevron-up
-        Show/hide discussion
-
-  .discussion-body.js-toggle-content
-    = render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note
diff --git a/app/views/projects/notes/discussions/_commit.html.haml b/app/views/projects/notes/discussions/_commit.html.haml
deleted file mode 100644
index 2a2ead58eeb5846383702cc16e29f54384df03e5..0000000000000000000000000000000000000000
--- a/app/views/projects/notes/discussions/_commit.html.haml
+++ /dev/null
@@ -1,25 +0,0 @@
-- note = discussion_notes.first
-- commit = note.noteable
-- commit_description = commit ? 'commit' : 'a deleted commit'
-.discussion.js-toggle-container{ class: note.discussion_id }
-  .discussion-header
-    = link_to_member(@project, note.author, avatar: false)
-    .inline.discussion-headline-light
-      = "#{note.author.to_reference} started a discussion on #{commit_description}"
-      - if commit
-        = link_to(commit.short_id, namespace_project_commit_path(note.project.namespace, note.project, note.noteable), class: 'monospace')
-      = time_ago_with_tooltip(note.created_at, placement: "bottom", html_class: "discussion_updated_ago")
-    .discussion-actions
-      = link_to "#", class: "note-action-button discussion-toggle-button js-toggle-button" do
-        %i.fa.fa-chevron-up
-        Show/hide discussion
-  .discussion-body.js-toggle-content
-    - if note.for_diff_line?
-      = render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note
-    - else
-      .panel.panel-default
-        .notes{ data: { discussion_id: discussion_notes.first.discussion_id } }
-          %ul.notes.timeline
-            = render discussion_notes
-        .discussion-reply-holder
-          = link_to_reply_diff(discussion_notes.first)
diff --git a/app/views/projects/notes/discussions/_diff.html.haml b/app/views/projects/notes/discussions/_diff.html.haml
deleted file mode 100644
index d46aab000c37560c75b28b38eacfa00218d9ae0d..0000000000000000000000000000000000000000
--- a/app/views/projects/notes/discussions/_diff.html.haml
+++ /dev/null
@@ -1,28 +0,0 @@
-- diff = note.diff
-- if diff
-  .diff-file
-    .diff-header
-      %span
-        - if diff.deleted_file
-          = diff.old_path
-        - else
-          = diff.new_path
-          - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
-            %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}"
-    .diff-content.code.js-syntax-highlight
-      %table
-        - note.truncated_diff_lines.each do |line|
-          - type = line.type
-          - line_code = generate_line_code(note.file_path, line)
-          %tr.line_holder{ id: line_code, class: "#{type}" }
-            - if type == "match"
-              %td.old_line.diff-line-num= "..."
-              %td.new_line.diff-line-num= "..."
-              %td.line_content.match= line.text
-            - else
-              %td.old_line.diff-line-num{ data: { linenumber: type == "new" ? "&nbsp;".html_safe : line.old_pos } }
-              %td.new_line.diff-line-num{ data: { linenumber: type == "old" ? "&nbsp;".html_safe : line.new_pos } }
-              %td.line_content{ class: ['noteable_line', type, line_code], line_code: line_code }= diff_line_content(line.text, type)
-
-              - if line_code == note.line_code
-                = render "projects/notes/diff_notes_with_reply", notes: discussion_notes
diff --git a/app/views/projects/notes/discussions/_diff_with_notes.html.haml b/app/views/projects/notes/discussions/_diff_with_notes.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..6401245bf73422cadf64943218e6faa466d0188a
--- /dev/null
+++ b/app/views/projects/notes/discussions/_diff_with_notes.html.haml
@@ -0,0 +1,30 @@
+- note = discussion_notes.first
+- diff = note.diff
+- return unless diff
+
+.diff-file
+  .diff-header
+    %span
+      - if diff.deleted_file
+        = diff.old_path
+      - else
+        = diff.new_path
+        - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
+          %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}"
+  .diff-content.code.js-syntax-highlight
+    %table
+      - note.truncated_diff_lines.each do |line|
+        - type = line.type
+        - line_code = generate_line_code(note.diff_file_path, line)
+        %tr.line_holder{ id: line_code, class: "#{type}" }
+          - if type == "match"
+            %td.old_line.diff-line-num= "..."
+            %td.new_line.diff-line-num= "..."
+            %td.line_content.match= line.text
+          - else
+            %td.old_line.diff-line-num{ data: { linenumber: type == "new" ? "&nbsp;".html_safe : line.old_pos } }
+            %td.new_line.diff-line-num{ data: { linenumber: type == "old" ? "&nbsp;".html_safe : line.new_pos } }
+            %td.line_content{ class: ['noteable_line', type, line_code], line_code: line_code }= diff_line_content(line.text, type)
+
+            - if line_code == note.line_code
+              = render "projects/notes/diff_notes_with_reply", notes: discussion_notes
diff --git a/app/views/projects/notes/discussions/_notes.html.haml b/app/views/projects/notes/discussions/_notes.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..e598e3c7c6346c798eb9a884325ee8fee7237c93
--- /dev/null
+++ b/app/views/projects/notes/discussions/_notes.html.haml
@@ -0,0 +1,7 @@
+- note = discussion_notes.first
+.panel.panel-default
+  .notes{ data: { discussion_id: note.discussion_id } }
+    %ul.notes.timeline
+      = render partial: "projects/notes/note", collection: discussion_notes, as: :note
+  .discussion-reply-holder
+    = link_to_reply_discussion(note)
diff --git a/app/views/projects/notes/discussions/_outdated.html.haml b/app/views/projects/notes/discussions/_outdated.html.haml
deleted file mode 100644
index 45141bcd1dfd59edf3e41cd94b67fc3e5a036f99..0000000000000000000000000000000000000000
--- a/app/views/projects/notes/discussions/_outdated.html.haml
+++ /dev/null
@@ -1,14 +0,0 @@
-- note = discussion_notes.first
-.discussion.js-toggle-container{ class: note.discussion_id }
-  .discussion-header
-    = link_to_member(@project, note.author, avatar: false)
-    .inline.discussion-headline-light
-      = "#{note.author.to_reference} started a discussion"
-      on the outdated diff
-      = time_ago_with_tooltip(note.created_at, placement: "bottom", html_class: "discussion_updated_ago")
-    .discussion-actions
-      = link_to "#", class: "note-action-button discussion-toggle-button js-toggle-button" do
-        %i.fa.fa-chevron-down
-        Show/hide discussion
-  .discussion-body.js-toggle-content.hide
-    = render "projects/notes/discussions/diff", discussion_notes: discussion_notes, note: note
diff --git a/db/migrate/20160508215820_add_type_to_notes.rb b/db/migrate/20160508215820_add_type_to_notes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..58944d4e651c4e44328deb6dfc317cac5f8724b2
--- /dev/null
+++ b/db/migrate/20160508215820_add_type_to_notes.rb
@@ -0,0 +1,5 @@
+class AddTypeToNotes < ActiveRecord::Migration
+  def change
+    add_column :notes, :type, :string
+  end
+end
diff --git a/db/migrate/20160508221410_set_type_on_legacy_diff_notes.rb b/db/migrate/20160508221410_set_type_on_legacy_diff_notes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c3f23d89d5a127a48363479d1e9c35175f726b2f
--- /dev/null
+++ b/db/migrate/20160508221410_set_type_on_legacy_diff_notes.rb
@@ -0,0 +1,5 @@
+class SetTypeOnLegacyDiffNotes < ActiveRecord::Migration
+  def change
+    execute "UPDATE notes SET type = 'LegacyDiffNote' WHERE line_code IS NOT NULL"
+  end
+end
diff --git a/db/migrate/20160516174813_add_send_user_confirmation_email_to_application_settings.rb b/db/migrate/20160516174813_add_send_user_confirmation_email_to_application_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c34e7ba540951aabcc12826936501d8b4c4b559d
--- /dev/null
+++ b/db/migrate/20160516174813_add_send_user_confirmation_email_to_application_settings.rb
@@ -0,0 +1,12 @@
+class AddSendUserConfirmationEmailToApplicationSettings < ActiveRecord::Migration
+  def up
+    add_column :application_settings, :send_user_confirmation_email, :boolean, default: false
+
+    #Sets confirmation email to true by default on existing installations.
+    execute "UPDATE application_settings SET send_user_confirmation_email=true"
+  end
+
+  def down
+    remove_column :application_settings, :send_user_confirmation_email
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index f09e4a262b4fafc86b0aef5cdf3be62b748b22f8..af4f4c609e7aab10c7129a4f2eaa4a66d7de5974 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -632,10 +632,11 @@ ActiveRecord::Schema.define(version: 20160509201028) do
     t.string   "line_code"
     t.string   "commit_id"
     t.integer  "noteable_id"
-    t.boolean  "system",        default: false, null: false
+    t.boolean  "system",            default: false, null: false
     t.text     "st_diff"
     t.integer  "updated_by_id"
-    t.boolean  "is_award",      default: false, null: false
+    t.boolean  "is_award",          default: false, null: false
+    t.string   "type"
   end
 
   add_index "notes", ["author_id"], name: "index_notes_on_author_id", using: :btree
diff --git a/doc/administration/environment_variables.md b/doc/administration/environment_variables.md
index 43ab153d76dc058cf99d4796ccc5292df14905c7..7f53915a4d7c861b023bdf7410483172ee387467 100644
--- a/doc/administration/environment_variables.md
+++ b/doc/administration/environment_variables.md
@@ -58,4 +58,4 @@ to the naming scheme `GITLAB_#{name in 1_settings.rb in upper case}`.
 
 It's possible to preconfigure the GitLab docker image by adding the environment
 variable `GITLAB_OMNIBUS_CONFIG` to the `docker run` command.
-For more information see the ['preconfigure-docker-container' section in the Omnibus documentation](http://doc.gitlab.com/omnibus/docker/#preconfigure-docker-container).
+For more information see the ['preconfigure-docker-container' section in the Omnibus documentation](http://docs.gitlab.com/omnibus/docker/#preconfigure-docker-container).
diff --git a/doc/administration/high_availability/load_balancer.md b/doc/administration/high_availability/load_balancer.md
index b1fe34ed9a1a307dd92ca21153f9603eef031e36..136f570ac2724388853e47ea0694042d59d5e7a0 100644
--- a/doc/administration/high_availability/load_balancer.md
+++ b/doc/administration/high_availability/load_balancer.md
@@ -60,4 +60,4 @@ Read more on high-availability configuration:
       configure custom domains with custom SSL, which would not be possible
       if SSL was terminated at the load balancer.
 
-[gitlab-pages]: http://doc.gitlab.com/ee/pages/administration.html
+[gitlab-pages]: http://docs.gitlab.com/ee/pages/administration.html
diff --git a/doc/administration/high_availability/nfs.md b/doc/administration/high_availability/nfs.md
index e4e124e200a2cff0164ad75c444a2dd3ee826519..49ff5d536a10cddaaa3cff9640644ee820cac921 100644
--- a/doc/administration/high_availability/nfs.md
+++ b/doc/administration/high_availability/nfs.md
@@ -113,4 +113,4 @@ Read more on high-availability configuration:
 1. [Configure the GitLab application servers](gitlab.md)
 1. [Configure the load balancers](load_balancer.md)
 
-[udp-log-shipping]: http://doc.gitlab.com/omnibus/settings/logs.html#udp-log-shipping-gitlab-enterprise-edition-only "UDP log shipping"
+[udp-log-shipping]: http://docs.gitlab.com/omnibus/settings/logs.html#udp-log-shipping-gitlab-enterprise-edition-only "UDP log shipping"
diff --git a/doc/api/services.md b/doc/api/services.md
index 7d45b2cf463f602faa2d3de8f3a1906a32b24a70..83ac7845156079c00b391a0957cf72605a682c0f 100644
--- a/doc/api/services.md
+++ b/doc/api/services.md
@@ -491,7 +491,7 @@ Jira issue tracker
 
 Set JIRA service for a project.
 
-> Setting `project_url`, `issues_url` and `new_issue_url` will allow a user to easily navigate to the Jira issue tracker. See the [integration doc](http://doc.gitlab.com/ce/integration/external-issue-tracker.html) for details.  Support for referencing commits and automatic closing of Jira issues directly from GitLab is [available in GitLab EE.](http://doc.gitlab.com/ee/integration/jira.html)
+> Setting `project_url`, `issues_url` and `new_issue_url` will allow a user to easily navigate to the Jira issue tracker. See the [integration doc](http://docs.gitlab.com/ce/integration/external-issue-tracker.html) for details.  Support for referencing commits and automatic closing of Jira issues directly from GitLab is [available in GitLab EE.](http://docs.gitlab.com/ee/integration/jira.html)
 
 ```
 PUT /projects/:id/services/jira
diff --git a/doc/development/doc_styleguide.md b/doc/development/doc_styleguide.md
index 187ec9e7b75c141f32880ec3e475f7681fd76b26..8292b393757adaa08eb50b87b0f862d2993cbb32 100644
--- a/doc/development/doc_styleguide.md
+++ b/doc/development/doc_styleguide.md
@@ -127,7 +127,7 @@ Inside the document:
     ```
   If the document you are editing resides in a place other than the GitLab CE/EE
   `doc/` directory, instead of the relative link, use the full path:
-  `http://doc.gitlab.com/ce/administration/restart_gitlab.html`.
+  `http://docs.gitlab.com/ce/administration/restart_gitlab.html`.
   Replace `reconfigure` with `restart` where appropriate.
 
 ## Installation guide
@@ -266,5 +266,5 @@ curl -X PUT -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" -d "restricted_signup_domai
 
 [cURL]: http://curl.haxx.se/ "cURL website"
 [single spaces]: http://www.slate.com/articles/technology/technology/2011/01/space_invaders.html
-[gfm]: http://doc.gitlab.com/ce/markdown/markdown.html#newlines "GitLab flavored markdown documentation"
+[gfm]: http://docs.gitlab.com/ce/markdown/markdown.html#newlines "GitLab flavored markdown documentation"
 [doc-restart]: ../administration/restart_gitlab.md "GitLab restart documentation"
diff --git a/doc/gitlab-basics/create-issue.md b/doc/gitlab-basics/create-issue.md
index 87f078def0422ba2e20943b0152bbc5eab5d1f44..5221d85b6610274dd129285b5ae29c0ce57a2e9a 100644
--- a/doc/gitlab-basics/create-issue.md
+++ b/doc/gitlab-basics/create-issue.md
@@ -24,4 +24,4 @@ You may assign the Issue to a user, add a milestone and add labels (they are all
 
 ![Submit new issue](basicsimages/submit_new_issue.png)
 
-Your Issue will now be added to the Issue Tracker and will be ready to be reviewed. You can comment on it and mention the people involved. You can also link Issues to the Merge Requests where the Issues are solved. To do this, you can use an [Issue closing pattern](http://doc.gitlab.com/ce/customization/issue_closing.html).
+Your Issue will now be added to the Issue Tracker and will be ready to be reviewed. You can comment on it and mention the people involved. You can also link Issues to the Merge Requests where the Issues are solved. To do this, you can use an [Issue closing pattern](http://docs.gitlab.com/ce/customization/issue_closing.html).
diff --git a/doc/gitlab-basics/create-project.md b/doc/gitlab-basics/create-project.md
index b545d62549d80356e16a8ccf756619b8e606b251..f737dffc0248ae9af553305fddc85bfc80785b9a 100644
--- a/doc/gitlab-basics/create-project.md
+++ b/doc/gitlab-basics/create-project.md
@@ -14,7 +14,7 @@ Fill out the required information:
 
 1. Select a [visibility level](https://gitlab.com/help/public_access/public_access)
 
-1. You can also [import your existing projects](http://doc.gitlab.com/ce/workflow/importing/README.html)
+1. You can also [import your existing projects](http://docs.gitlab.com/ce/workflow/importing/README.html)
 
 1. Click on "create project"
 
diff --git a/doc/hooks/custom_hooks.md b/doc/hooks/custom_hooks.md
index dcdf49d3379702ffa9a7b6b6964a115037a632ec..820934f97f11883d2cf00ba62ebce52bc8a0b0de 100644
--- a/doc/hooks/custom_hooks.md
+++ b/doc/hooks/custom_hooks.md
@@ -2,7 +2,7 @@
 
 **Note: Custom git hooks must be configured on the filesystem of the GitLab
 server. Only GitLab server administrators will be able to complete these tasks.
-Please explore [webhooks](../web_hooks/web_hooks.md) as an option if you do not have filesystem access. For a user configurable Git Hooks interface, please see [GitLab Enterprise Edition Git Hooks](http://doc.gitlab.com/ee/git_hooks/git_hooks.html).**
+Please explore [webhooks](../web_hooks/web_hooks.md) as an option if you do not have filesystem access. For a user configurable Git Hooks interface, please see [GitLab Enterprise Edition Git Hooks](http://docs.gitlab.com/ee/git_hooks/git_hooks.html).**
 
 Git natively supports hooks that are executed on different actions.
 Examples of server-side git hooks include pre-receive, post-receive, and update.
diff --git a/doc/install/installation.md b/doc/install/installation.md
index 44ae0be406c3b94afa525228391a62f83774bbc3..fa11eb9ba6a55dddde0d46a7d836506e88f51b1f 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -6,7 +6,7 @@ Since an installation from source is a lot of work and error prone we strongly r
 
 One reason the Omnibus package is more reliable is its use of Runit to restart any of the GitLab processes in case one crashes.
 On heavily used GitLab instances the memory usage of the Sidekiq background worker will grow over time.
-Omnibus packages solve this by [letting the Sidekiq terminate gracefully](http://doc.gitlab.com/ce/operations/sidekiq_memory_killer.html) if it uses too much memory.
+Omnibus packages solve this by [letting the Sidekiq terminate gracefully](http://docs.gitlab.com/ce/operations/sidekiq_memory_killer.html) if it uses too much memory.
 After this termination Runit will detect Sidekiq is not running and will start it.
 Since installations from source don't have Runit, Sidekiq can't be terminated and its memory usage will grow over time.
 
diff --git a/doc/install/relative_url.md b/doc/install/relative_url.md
index 0245febfcd878cbffd1c18dfd610485e2c76df8b..44d2a14f3666edb6636fc5eeb522e8ea795de4e5 100644
--- a/doc/install/relative_url.md
+++ b/doc/install/relative_url.md
@@ -132,5 +132,5 @@ To disable the relative URL:
 1.  Follow the same as above starting from 2. and set up the
     GitLab URL to one that doesn't contain a relative path.
 
-[omnibus-rel]: http://doc.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab "How to setup relative URL in Omnibus GitLab"
+[omnibus-rel]: http://docs.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab "How to setup relative URL in Omnibus GitLab"
 [restart gitlab]: ../administration/restart_gitlab.md#installations-from-source "How to restart GitLab"
diff --git a/doc/integration/README.md b/doc/integration/README.md
index 6fe04aa2a0639f40cb95331016b8db47a0aa9bce..fd330dd7a7deae5c9bd99398697ad2705d34b46d 100644
--- a/doc/integration/README.md
+++ b/doc/integration/README.md
@@ -19,7 +19,7 @@ See the documentation below for details on how to configure these services.
 
 GitLab Enterprise Edition contains [advanced Jenkins support][jenkins].
 
-[jenkins]: http://doc.gitlab.com/ee/integration/jenkins.html
+[jenkins]: http://docs.gitlab.com/ee/integration/jenkins.html
 
 
 ## Project services
diff --git a/doc/intro/README.md b/doc/intro/README.md
index ab298d3808e251057cc171d497c305b43e5927dc..382d10aaf40f5beb518a37b3b7cc3352c4c74b7c 100644
--- a/doc/intro/README.md
+++ b/doc/intro/README.md
@@ -39,4 +39,4 @@ Install and update your GitLab installation.
 
 - [Install GitLab](https://about.gitlab.com/installation/)
 - [Update GitLab](https://about.gitlab.com/update/)
-- [Explore Omnibus GitLab configuration options](http://doc.gitlab.com/omnibus/settings/configuration.html)
+- [Explore Omnibus GitLab configuration options](http://docs.gitlab.com/omnibus/settings/configuration.html)
diff --git a/doc/logs/logs.md b/doc/logs/logs.md
index 27937e517644922d36930c923e1bd90f91c58e83..ef5affa2ebd59cc14a9de924190d2d43b1ec817f 100644
--- a/doc/logs/logs.md
+++ b/doc/logs/logs.md
@@ -1,6 +1,6 @@
 ## Log system
 GitLab has advanced log system so everything is logging and you can analize your instance using various system log files.
-In addition to system log files, GitLab Enterprise Edition comes with Audit Events. Find more about them [in Audit Events documentation](http://doc.gitlab.com/ee/administration/audit_events.html)
+In addition to system log files, GitLab Enterprise Edition comes with Audit Events. Find more about them [in Audit Events documentation](http://docs.gitlab.com/ee/administration/audit_events.html)
 
 System log files are typically plain text in a standard log file format. This guide talks about how to read and use these system log files.
 
diff --git a/doc/raketasks/README.md b/doc/raketasks/README.md
index 6be954ad68ba65ec530da46f4c270dda9b2fb9c7..a49c43b8ef2bd0f40c62a657aa1b4e0c36ebc8d4 100644
--- a/doc/raketasks/README.md
+++ b/doc/raketasks/README.md
@@ -8,4 +8,4 @@
 - [User management](user_management.md)
 - [Webhooks](web_hooks.md)
 - [Import](import.md) of git repositories in bulk
-- [Rebuild authorized_keys file](http://doc.gitlab.com/ce/raketasks/maintenance.html#rebuild-authorized_keys-file) task for administrators
+- [Rebuild authorized_keys file](http://docs.gitlab.com/ce/raketasks/maintenance.html#rebuild-authorized_keys-file) task for administrators
diff --git a/doc/security/README.md b/doc/security/README.md
index 4cd0fdd409443e6889a8232fc28cdd7603c61393..38706e48ec5713c7cbb4b45daafb26f8c0bd131b 100644
--- a/doc/security/README.md
+++ b/doc/security/README.md
@@ -8,3 +8,4 @@
 - [User File Uploads](user_file_uploads.md)
 - [How we manage the CRIME vulnerability](crime_vulnerability.md)
 - [Enforce Two-factor authentication](two_factor_authentication.md)
+- [Send email confirmation on sign-up](user_email_confirmation.md)
diff --git a/doc/security/user_email_confirmation.md b/doc/security/user_email_confirmation.md
new file mode 100644
index 0000000000000000000000000000000000000000..4293944ae8b75e83d0b0d92d934e49963d581faa
--- /dev/null
+++ b/doc/security/user_email_confirmation.md
@@ -0,0 +1,7 @@
+# User email confirmation at sign-up
+
+Gitlab admin can enable email confirmation on sign-up, if you want to confirm all
+user emails before they are able to sign-in.
+
+In the Admin area under **Settings** (`/admin/application_settings`), go to section
+**Sign-in Restrictions** and look for **Send confirmation email on sign-up** option.
diff --git a/doc/update/README.md b/doc/update/README.md
index a770633c9b8f9ace9b78b7950c9ac6c9d7dc30ff..975d72164b4eb050ff53b5e56cd87ca7ec9af8f1 100644
--- a/doc/update/README.md
+++ b/doc/update/README.md
@@ -29,7 +29,7 @@ Based on your installation, choose a section below that fits your needs.
 
 ## Omnibus Packages
 
-- The [Omnibus update guide](http://doc.gitlab.com/omnibus/update/README.html)
+- The [Omnibus update guide](http://docs.gitlab.com/omnibus/update/README.html)
   contains the steps needed to update an Omnibus GitLab package.
 
 ## Installation from source
@@ -86,10 +86,10 @@ possible.
   information about configuring GitLab to work with a MySQL database.
 - [Restoring from backup after a failed upgrade](restore_after_failure.md)
 
-[omnidocker]: http://doc.gitlab.com/omnibus/docker/README.html
+[omnidocker]: http://docs.gitlab.com/omnibus/docker/README.html
 [source-ee]: https://gitlab.com/gitlab-org/gitlab-ee/tree/master/doc/update
 [source-ce]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/update
 [ee-ce]: ../downgrade_ee_to_ce/README.md
 [ce]: https://about.gitlab.com/features/#community
 [ee]: https://about.gitlab.com/features/#enterprise
-[omni-ce-ee]: http://doc.gitlab.com/omnibus/update/README.html#from-community-edition-to-enterprise-edition
+[omni-ce-ee]: http://docs.gitlab.com/omnibus/update/README.html#from-community-edition-to-enterprise-edition
diff --git a/doc/workflow/gitlab_flow.md b/doc/workflow/gitlab_flow.md
index 1b354bcc0f1c875ea44ff7e482a30c7dc65b610e..2b2f140f8bf195ad357b607d0337771023b549fd 100644
--- a/doc/workflow/gitlab_flow.md
+++ b/doc/workflow/gitlab_flow.md
@@ -131,7 +131,7 @@ When you feel comfortable with it to be merged you assign it to the person that
 There is room for more feedback and after the assigned person feels comfortable with the result the branch is merged.
 If the assigned person does not feel comfortable they can close the merge request without merging.
 
-In GitLab it is common to protect the long-lived branches (e.g. the master branch) so that normal developers [can't modify these protected branches](http://doc.gitlab.com/ce/permissions/permissions.html).
+In GitLab it is common to protect the long-lived branches (e.g. the master branch) so that normal developers [can't modify these protected branches](http://docs.gitlab.com/ce/permissions/permissions.html).
 So if you want to merge it into a protected branch you assign it to someone with master authorizations.
 
 ## Issues with GitLab flow
@@ -187,7 +187,7 @@ If you have an issue that spans across multiple repositories, the best thing is
 ![Vim screen showing the rebase view](rebase.png)
 
 With git you can use an interactive rebase (`rebase -i`) to squash multiple commits into one and reorder them.
-In GitLab EE and .com you can also [rebase before merge](http://doc.gitlab.com/ee/workflow/rebase_before_merge.html) from the web interface.
+In GitLab EE and .com you can also [rebase before merge](http://docs.gitlab.com/ee/workflow/rebase_before_merge.html) from the web interface.
 This functionality is useful if you made a couple of commits for small changes during development and want to replace them with a single commit or if you want to make the order more logical.
 However you should never rebase commits you have pushed to a remote server.
 Somebody can have referred to the commits or cherry-picked them.
diff --git a/doc/workflow/groups.md b/doc/workflow/groups.md
index 52bf611dc5e2a83ee68a46b616b71de77f88e970..34ada1774d8721cbe383789f32e0523b93eb3dbc 100644
--- a/doc/workflow/groups.md
+++ b/doc/workflow/groups.md
@@ -54,7 +54,7 @@ If necessary, you can increase the access level of an individual user for a spec
 ## Managing group memberships via LDAP
 
 In GitLab Enterprise Edition it is possible to manage GitLab group memberships using LDAP groups.
-See [the GitLab Enterprise Edition documentation](http://doc.gitlab.com/ee/integration/ldap.html) for more information.
+See [the GitLab Enterprise Edition documentation](http://docs.gitlab.com/ee/integration/ldap.html) for more information.
 
 ## Allowing only admins to create groups
 
diff --git a/doc/workflow/importing/import_projects_from_github.md b/doc/workflow/importing/import_projects_from_github.md
index e670e415c7151ae9624ca1fce9bd390a483411a9..a7dfac2c12066139773216e2e93f0a2b256b31be 100644
--- a/doc/workflow/importing/import_projects_from_github.md
+++ b/doc/workflow/importing/import_projects_from_github.md
@@ -44,5 +44,5 @@ case the namespace is taken, the project will be imported on the user's
 namespace.
 
 [gh-import]: ../../integration/github.md "GitHub integration"
-[ee-gh]: http://doc.gitlab.com/ee/integration/github.html "GitHub integration for GitLab EE"
+[ee-gh]: http://docs.gitlab.com/ee/integration/github.html "GitHub integration for GitLab EE"
 [new-project]: ../../gitlab-basics/create-project.md "How to create a new project in GitLab"
diff --git a/doc/workflow/importing/import_projects_from_gitlab_com.md b/doc/workflow/importing/import_projects_from_gitlab_com.md
index 1117db98e7e40d18ad0f7d6e3fb349bafa55df51..dcc00074b750e392459ad4eb24f44b2c00a1c534 100644
--- a/doc/workflow/importing/import_projects_from_gitlab_com.md
+++ b/doc/workflow/importing/import_projects_from_gitlab_com.md
@@ -2,7 +2,7 @@
 
 You can import your existing GitLab.com projects to your GitLab instance. But keep in mind that it is possible only if
 GitLab support is enabled on your GitLab instance. 
-You can read more about GitLab support [here](http://doc.gitlab.com/ce/integration/gitlab.html)
+You can read more about GitLab support [here](http://docs.gitlab.com/ce/integration/gitlab.html)
 To get to the importer page you need to go to "New project" page.
 
 ![New project page](gitlab_importer/new_project_page.png)
diff --git a/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md b/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md
index 83db44c10b1797709e83a912bed1c8ef01918f99..1295dfbd770db177e433f11fd3d011f548046be0 100644
--- a/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md
+++ b/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md
@@ -4,7 +4,7 @@ Managing large files such as audio, video and graphics files has always been one
 of the shortcomings of Git. The general recommendation is to not have Git repositories
 larger than 1GB to preserve performance.
 
-GitLab already supports [managing large files with git annex](http://doc.gitlab.com/ee/workflow/git_annex.html)
+GitLab already supports [managing large files with git annex](http://docs.gitlab.com/ee/workflow/git_annex.html)
 (EE only), however in certain environments it is not always convenient to use
 different commands to differentiate between the large files and regular ones.
 
diff --git a/features/steps/shared/diff_note.rb b/features/steps/shared/diff_note.rb
index e846c52d474ecdcfddf8d97d00cc92b957a43f60..e8b1e4b4879baa3042cfa3537a5adc98466e3365 100644
--- a/features/steps/shared/diff_note.rb
+++ b/features/steps/shared/diff_note.rb
@@ -23,7 +23,7 @@ module SharedDiffNote
     page.within(diff_file_selector) do
       click_diff_line(sample_commit.line_code)
 
-      page.within("form[id$='#{sample_commit.line_code}']") do
+      page.within("form[id$='#{sample_commit.line_code}-true']") do
         fill_in "note[note]", with: "Typo, please fix"
         find(".js-comment-button").trigger("click")
         sleep 0.05
@@ -33,7 +33,7 @@ module SharedDiffNote
 
   step 'I leave a diff comment in a parallel view on the left side like "Old comment"' do
     click_parallel_diff_line(sample_commit.line_code, 'old')
-    page.within("#{diff_file_selector} form[id$='#{sample_commit.line_code}']") do
+    page.within("#{diff_file_selector} form[id$='#{sample_commit.line_code}-true']") do
       fill_in "note[note]", with: "Old comment"
       find(".js-comment-button").trigger("click")
     end
@@ -41,7 +41,7 @@ module SharedDiffNote
 
   step 'I leave a diff comment in a parallel view on the right side like "New comment"' do
     click_parallel_diff_line(sample_commit.line_code, 'new')
-    page.within("#{diff_file_selector} form[id$='#{sample_commit.line_code}']") do
+    page.within("#{diff_file_selector} form[id$='#{sample_commit.line_code}-true']") do
       fill_in "note[note]", with: "New comment"
       find(".js-comment-button").trigger("click")
     end
@@ -51,7 +51,7 @@ module SharedDiffNote
     page.within(diff_file_selector) do
       click_diff_line(sample_commit.line_code)
 
-      page.within("form[id$='#{sample_commit.line_code}']") do
+      page.within("form[id$='#{sample_commit.line_code}-true']") do
         fill_in "note[note]", with: "Should fix it :smile:"
         find('.js-md-preview-button').click
       end
@@ -62,7 +62,7 @@ module SharedDiffNote
     page.within(diff_file_selector) do
       click_diff_line(sample_commit.del_line_code)
 
-      page.within("form[id$='#{sample_commit.del_line_code}']") do
+      page.within("form[id$='#{sample_commit.del_line_code}-true']") do
         fill_in "note[note]", with: "DRY this up"
         find('.js-md-preview-button').click
       end
@@ -91,7 +91,7 @@ module SharedDiffNote
     page.within(diff_file_selector) do
       click_diff_line(sample_commit.line_code)
 
-      page.within("form[id$='#{sample_commit.line_code}']") do
+      page.within("form[id$='#{sample_commit.line_code}-true']") do
         fill_in 'note[note]', with: ':smile:'
         click_button('Comment')
       end
diff --git a/lib/api/commits.rb b/lib/api/commits.rb
index 93a3a5ce08908ce0355ee4996bb26a54eb1d100e..4a11c8e3620cc261a8b0c4dd12b1381a35c93abb 100644
--- a/lib/api/commits.rb
+++ b/lib/api/commits.rb
@@ -107,6 +107,8 @@ module API
 
             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
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 24ec551d7204afed649e62b42dcfad5eb5969922..dbd03ea74faad7e1a61b8eeb1cbf48c7d7f14490 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -228,9 +228,9 @@ module API
 
     class CommitNote < Grape::Entity
       expose :note
-      expose(:path) { |note| note.diff_file_name }
-      expose(:line) { |note| note.diff_new_line }
-      expose(:line_type) { |note| note.diff_line_type }
+      expose(:path) { |note| note.diff_file_path if note.legacy_diff_note? }
+      expose(:line) { |note| note.diff_new_line if note.legacy_diff_note? }
+      expose(:line_type) { |note| note.diff_line_type if note.legacy_diff_note? }
       expose :author, using: Entities::UserBasic
       expose :created_at
     end
diff --git a/lib/gitlab/github_import/branch_formatter.rb b/lib/gitlab/github_import/branch_formatter.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a15fc84b4182b3f5beed5005410688f4b03704cf
--- /dev/null
+++ b/lib/gitlab/github_import/branch_formatter.rb
@@ -0,0 +1,29 @@
+module Gitlab
+  module GithubImport
+    class BranchFormatter < BaseFormatter
+      delegate :repo, :sha, :ref, to: :raw_data
+
+      def exists?
+        project.repository.branch_exists?(ref)
+      end
+
+      def name
+        @name ||= exists? ? ref : "#{ref}-#{short_id}"
+      end
+
+      def valid?
+        repo.present?
+      end
+
+      def valid?
+        repo.present?
+      end
+
+      private
+
+      def short_id
+        sha.to_s[0..7]
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb
index 0f9e3ee14ee742bbc31c419c56334b7d5abcff73..408d9b796325c3f2b5403d137e0dc73f3ba7003e 100644
--- a/lib/gitlab/github_import/importer.rb
+++ b/lib/gitlab/github_import/importer.rb
@@ -3,12 +3,15 @@ module Gitlab
     class Importer
       include Gitlab::ShellAdapter
 
-      attr_reader :project, :client
+      attr_reader :client, :project, :repo, :repo_url
 
       def initialize(project)
-        @project = project
-        if import_data_credentials
-          @client = Client.new(import_data_credentials[:user])
+        @project  = project
+        @repo     = project.import_source
+        @repo_url = project.import_url
+
+        if credentials
+          @client = Client.new(credentials[:user])
           @formatter = Gitlab::ImportFormatter.new
         else
           raise Projects::ImportService::Error, "Unable to find project import data credentials for project ID: #{@project.id}"
@@ -22,12 +25,12 @@ module Gitlab
 
       private
 
-      def import_data_credentials
-        @import_data_credentials ||= project.import_data.credentials if project.import_data
+      def credentials
+        @credentials ||= project.import_data.credentials if project.import_data
       end
 
       def import_labels
-        client.labels(project.import_source).each do |raw_data|
+        client.labels(repo).each do |raw_data|
           Label.create!(LabelFormatter.new(project, raw_data).attributes)
         end
 
@@ -37,7 +40,7 @@ module Gitlab
       end
 
       def import_milestones
-        client.list_milestones(project.import_source, state: :all).each do |raw_data|
+        client.list_milestones(repo, state: :all).each do |raw_data|
           Milestone.create!(MilestoneFormatter.new(project, raw_data).attributes)
         end
 
@@ -47,9 +50,7 @@ module Gitlab
       end
 
       def import_issues
-        client.list_issues(project.import_source, state: :all,
-                                                  sort: :created,
-                                                  direction: :asc).each do |raw_data|
+        client.list_issues(repo, state: :all, sort: :created, direction: :asc).each do |raw_data|
           gh_issue = IssueFormatter.new(project, raw_data)
 
           if gh_issue.valid?
@@ -68,29 +69,50 @@ module Gitlab
       end
 
       def import_pull_requests
-        client.pull_requests(project.import_source, state: :all,
-                                                    sort: :created,
-                                                    direction: :asc).each do |raw_data|
-          pull_request = PullRequestFormatter.new(project, raw_data)
-
-          if pull_request.valid?
-            merge_request = MergeRequest.new(pull_request.attributes)
-
-            if merge_request.save
-              apply_labels(pull_request.number, merge_request)
-              import_comments(pull_request.number, merge_request)
-              import_comments_on_diff(pull_request.number, merge_request)
-            end
+        pull_requests = client.pull_requests(repo, state: :all, sort: :created, direction: :asc)
+                              .map { |raw| PullRequestFormatter.new(project, raw) }
+                              .select(&:valid?)
+
+        source_branches_removed = pull_requests.reject(&:source_branch_exists?).map { |pr| [pr.source_branch_name, pr.source_branch_sha] }
+        target_branches_removed = pull_requests.reject(&:target_branch_exists?).map { |pr| [pr.target_branch_name, pr.target_branch_sha] }
+        branches_removed = source_branches_removed | target_branches_removed
+
+        create_refs(branches_removed)
+
+        pull_requests.each do |pull_request|
+          merge_request = MergeRequest.new(pull_request.attributes)
+
+          if merge_request.save
+            apply_labels(pull_request.number, merge_request)
+            import_comments(pull_request.number, merge_request)
+            import_comments_on_diff(pull_request.number, merge_request)
           end
         end
 
+        delete_refs(branches_removed)
+
         true
       rescue ActiveRecord::RecordInvalid => e
         raise Projects::ImportService::Error, e.message
       end
 
+      def create_refs(branches)
+        branches.each do |name, sha|
+          client.create_ref(repo, "refs/heads/#{name}", sha)
+        end
+
+        project.repository.fetch_ref(repo_url, '+refs/heads/*', 'refs/heads/*')
+      end
+
+      def delete_refs(branches)
+        branches.each do |name, _|
+          client.delete_ref(repo, "heads/#{name}")
+          project.repository.rm_branch(project.creator, name)
+        end
+      end
+
       def apply_labels(number, issuable)
-        issue = client.issue(project.import_source, number)
+        issue = client.issue(repo, number)
 
         if issue.labels.count > 0
           label_ids = issue.labels.map do |raw|
@@ -102,12 +124,12 @@ module Gitlab
       end
 
       def import_comments(issue_number, noteable)
-        comments = client.issue_comments(project.import_source, issue_number)
+        comments = client.issue_comments(repo, issue_number)
         create_comments(comments, noteable)
       end
 
       def import_comments_on_diff(pull_request_number, merge_request)
-        comments = client.pull_request_comments(project.import_source, pull_request_number)
+        comments = client.pull_request_comments(repo, pull_request_number)
         create_comments(comments, merge_request)
       end
 
diff --git a/lib/gitlab/github_import/pull_request_formatter.rb b/lib/gitlab/github_import/pull_request_formatter.rb
index d21b942ad4bc54064b46b1a365c67ac79a134c65..574737b31c1f7ad3da8e3947b790885ca4528263 100644
--- a/lib/gitlab/github_import/pull_request_formatter.rb
+++ b/lib/gitlab/github_import/pull_request_formatter.rb
@@ -1,15 +1,20 @@
 module Gitlab
   module GithubImport
     class PullRequestFormatter < BaseFormatter
+      delegate :exists?, :name, :project, :repo, :sha, to: :source_branch, prefix: true
+      delegate :exists?, :name, :project, :repo, :sha, to: :target_branch, prefix: true
+
       def attributes
         {
           iid: number,
           title: raw_data.title,
           description: description,
-          source_project: source_project,
-          source_branch: source_branch.name,
-          target_project: target_project,
-          target_branch: target_branch.name,
+          source_project: source_branch_project,
+          source_branch: source_branch_name,
+          head_source_sha: source_branch_sha,
+          target_project: target_branch_project,
+          target_branch: target_branch_name,
+          base_target_sha: target_branch_sha,
           state: state,
           milestone: milestone,
           author_id: author_id,
@@ -24,7 +29,15 @@ module Gitlab
       end
 
       def valid?
-        !cross_project? && source_branch.present? && target_branch.present?
+        source_branch.valid? && target_branch.valid? && !cross_project?
+      end
+
+      def source_branch
+        @source_branch ||= BranchFormatter.new(project, raw_data.head)
+      end
+
+      def target_branch
+        @target_branch ||= BranchFormatter.new(project, raw_data.base)
       end
 
       private
@@ -52,7 +65,7 @@ module Gitlab
       end
 
       def cross_project?
-        source_repo.present? && target_repo.present? && source_repo.id != target_repo.id
+        source_branch_repo.id != target_branch_repo.id
       end
 
       def description
@@ -65,30 +78,6 @@ module Gitlab
         end
       end
 
-      def source_project
-        project
-      end
-
-      def source_repo
-        raw_data.head.repo
-      end
-
-      def source_branch
-        source_project.repository.find_branch(raw_data.head.ref)
-      end
-
-      def target_project
-        project
-      end
-
-      def target_repo
-        raw_data.base.repo
-      end
-
-      def target_branch
-        target_project.repository.find_branch(raw_data.base.ref)
-      end
-
       def state
         @state ||= case true
                    when raw_data.state == 'closed' && raw_data.merged_at.present?
diff --git a/lib/gitlab/metrics/subscribers/rails_cache.rb b/lib/gitlab/metrics/subscribers/rails_cache.rb
index 49e5f86e6e6e8be719fc286992419c908fe7d279..8e345e8ae4ac6ff0d6993a07764bce2d0af5d4d1 100644
--- a/lib/gitlab/metrics/subscribers/rails_cache.rb
+++ b/lib/gitlab/metrics/subscribers/rails_cache.rb
@@ -6,26 +6,28 @@ module Gitlab
         attach_to :active_support
 
         def cache_read(event)
-          increment(:cache_read_duration, event.duration)
+          increment(:cache_read, event.duration)
         end
 
         def cache_write(event)
-          increment(:cache_write_duration, event.duration)
+          increment(:cache_write, event.duration)
         end
 
         def cache_delete(event)
-          increment(:cache_delete_duration, event.duration)
+          increment(:cache_delete, event.duration)
         end
 
         def cache_exist?(event)
-          increment(:cache_exists_duration, event.duration)
+          increment(:cache_exists, event.duration)
         end
 
         def increment(key, duration)
           return unless current_transaction
 
           current_transaction.increment(:cache_duration, duration)
-          current_transaction.increment(key, duration)
+          current_transaction.increment(:cache_count, 1)
+          current_transaction.increment("#{key}_duration".to_sym, duration)
+          current_transaction.increment("#{key}_count".to_sym, 1)
         end
 
         private
diff --git a/lib/gitlab/url_builder.rb b/lib/gitlab/url_builder.rb
index 2bbbd3074e86f7fbe3bc9160ea175468391c9f89..fe65c246101e99c4aeac07f576a36f85c6491168 100644
--- a/lib/gitlab/url_builder.rb
+++ b/lib/gitlab/url_builder.rb
@@ -62,7 +62,7 @@ module Gitlab
     end
 
     def wiki_page_url
-      "#{Gitlab.config.gitlab.url}#{object.wiki.wiki_base_path}/#{object.slug}"
+      namespace_project_wiki_url(object.wiki.project.namespace, object.wiki.project, object.slug)
     end
   end
 end
diff --git a/public/robots.txt b/public/robots.txt
index 4f616c7f4c1cacff6e93558f47911b883fb5cd76..334f4c035334f74dbb8dca25eddc0d95619fed64 100644
--- a/public/robots.txt
+++ b/public/robots.txt
@@ -65,3 +65,4 @@ Disallow: /*/*/deploy_keys
 Disallow: /*/*/hooks
 Disallow: /*/*/services
 Disallow: /*/*/protected_branches
+Disallow: /*/*/uploads/
diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb
index ce2a62ae1fd3319d7b03ac62d7c579a1eca07264..6caf37ddc2c3057b71ca0fc4ab4e060ea80926a5 100644
--- a/spec/controllers/admin/users_controller_spec.rb
+++ b/spec/controllers/admin/users_controller_spec.rb
@@ -114,6 +114,82 @@ describe Admin::UsersController do
     end
   end
 
+  describe 'POST update' do
+    context 'when the password has changed' do
+      def update_password(user, password, password_confirmation = nil)
+        params = {
+          id: user.to_param,
+          user: {
+            password: password,
+            password_confirmation: password_confirmation || password
+          }
+        }
+
+        post :update, params
+      end
+
+      context 'when the new password is valid' do
+        it 'redirects to the user' do
+          update_password(user, 'AValidPassword1')
+
+          expect(response).to redirect_to(admin_user_path(user))
+        end
+
+        it 'updates the password' do
+          update_password(user, 'AValidPassword1')
+
+          expect { user.reload }.to change { user.encrypted_password }
+        end
+
+        it 'sets the new password to expire immediately' do
+          update_password(user, 'AValidPassword1')
+
+          expect { user.reload }.to change { user.password_expires_at }.to(a_value <= Time.now)
+        end
+      end
+
+      context 'when the new password is invalid' do
+        it 'shows the edit page again' do
+          update_password(user, 'invalid')
+
+          expect(response).to render_template(:edit)
+        end
+
+        it 'returns the error message' do
+          update_password(user, 'invalid')
+
+          expect(assigns[:user].errors).to contain_exactly(a_string_matching(/too short/))
+        end
+
+        it 'does not update the password' do
+          update_password(user, 'invalid')
+
+          expect { user.reload }.not_to change { user.encrypted_password }
+        end
+      end
+
+      context 'when the new password does not match the password confirmation' do
+        it 'shows the edit page again' do
+          update_password(user, 'AValidPassword1', 'AValidPassword2')
+
+          expect(response).to render_template(:edit)
+        end
+
+        it 'returns the error message' do
+          update_password(user, 'AValidPassword1', 'AValidPassword2')
+
+          expect(assigns[:user].errors).to contain_exactly(a_string_matching(/doesn't match/))
+        end
+
+        it 'does not update the password' do
+          update_password(user, 'AValidPassword1', 'AValidPassword2')
+
+          expect { user.reload }.not_to change { user.encrypted_password }
+        end
+      end
+    end
+  end
+
   describe "POST impersonate" do
     context "when the user is blocked" do
       before do
diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..df70a589a89cb7a7b620652d3720a0252b38410d
--- /dev/null
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -0,0 +1,33 @@
+require 'spec_helper'
+
+describe RegistrationsController do
+  describe '#create' do
+    around(:each) do |example|
+      perform_enqueued_jobs do
+        example.run
+      end
+    end
+
+    let(:user_params) { { user: { name: "new_user", username: "new_username", email: "new@user.com", password: "Any_password" } } }
+
+    context 'when sending email confirmation' do
+      before { allow(current_application_settings).to receive(:send_user_confirmation_email).and_return(false) }
+
+      it 'logs user in directly' do
+        post(:create, user_params)
+        expect(ActionMailer::Base.deliveries.last).to be_nil
+        expect(subject.current_user).to_not be_nil
+      end
+    end
+
+    context 'when not sending email confirmation' do
+      before { allow(current_application_settings).to receive(:send_user_confirmation_email).and_return(true) }
+
+      it 'does not authenticate user and sends confirmation email' do
+        post(:create, user_params)
+        expect(ActionMailer::Base.deliveries.last.to.first).to eq(user_params[:user][:email])
+        expect(subject.current_user).to be_nil
+      end
+    end
+  end
+end
diff --git a/spec/factories/notes.rb b/spec/factories/notes.rb
index 840b13196a674a504ff8b1f8145c95e4c897ac5a..26719f2652c277f2ab4b7c0fff0b0a957a62d2bc 100644
--- a/spec/factories/notes.rb
+++ b/spec/factories/notes.rb
@@ -9,10 +9,10 @@ FactoryGirl.define do
     author
 
     factory :note_on_commit,             traits: [:on_commit]
-    factory :note_on_commit_diff,        traits: [:on_commit, :on_diff]
+    factory :note_on_commit_diff,        traits: [:on_commit, :on_diff], class: LegacyDiffNote
     factory :note_on_issue,              traits: [:on_issue], aliases: [:votable_note]
     factory :note_on_merge_request,      traits: [:on_merge_request]
-    factory :note_on_merge_request_diff, traits: [:on_merge_request, :on_diff]
+    factory :note_on_merge_request_diff, traits: [:on_merge_request, :on_diff], class: LegacyDiffNote
     factory :note_on_project_snippet,    traits: [:on_project_snippet]
     factory :system_note,                traits: [:system]
     factory :downvote_note,              traits: [:award, :downvote]
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index 4570e4091284cea19d32166a21f45192814babef..6dee0cd8d47d63c479255c1e7f791e358f86d19d 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -210,6 +210,8 @@ describe "Admin::Users", feature: true  do
       before do
         fill_in "user_name", with: "Big Bang"
         fill_in "user_email", with: "bigbang@mail.com"
+        fill_in "user_password", with: "AValidPassword1"
+        fill_in "user_password_confirmation", with: "AValidPassword1"
         check "user_admin"
         click_button "Save changes"
       end
@@ -223,6 +225,7 @@ describe "Admin::Users", feature: true  do
         @simple_user.reload
         expect(@simple_user.name).to eq('Big Bang')
         expect(@simple_user.is_admin?).to be_truthy
+        expect(@simple_user.password_expires_at).to be <= Time.now
       end
     end
   end
diff --git a/spec/features/merge_requests/user_lists_merge_requests_spec.rb b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
index cc7f78e732503fb9c2cc6b0b8dfa348d9b1347dc..2c7e1c748adfdda5b2567cb8b5412a02a6638ffc 100644
--- a/spec/features/merge_requests/user_lists_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
@@ -38,6 +38,7 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
     expect(page).to have_content 'lfs'
     expect(page).not_to have_content 'fix'
     expect(page).not_to have_content 'markdown'
+    expect(count_merge_requests).to eq(1)
   end
 
   it 'filters on a specific assignee' do
@@ -46,6 +47,7 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
     expect(page).not_to have_content 'lfs'
     expect(page).to have_content 'fix'
     expect(page).to have_content 'markdown'
+    expect(count_merge_requests).to eq(2)
   end
 
   it 'sorts by newest' do
@@ -53,6 +55,7 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
 
     expect(first_merge_request).to include('lfs')
     expect(last_merge_request).to include('fix')
+    expect(count_merge_requests).to eq(3)
   end
 
   it 'sorts by oldest' do
@@ -60,30 +63,35 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
 
     expect(first_merge_request).to include('fix')
     expect(last_merge_request).to include('lfs')
+    expect(count_merge_requests).to eq(3)
   end
 
   it 'sorts by last updated' do
     visit_merge_requests(project, sort: sort_value_recently_updated)
 
     expect(first_merge_request).to include('lfs')
+    expect(count_merge_requests).to eq(3)
   end
 
   it 'sorts by oldest updated' do
     visit_merge_requests(project, sort: sort_value_oldest_updated)
 
     expect(first_merge_request).to include('markdown')
+    expect(count_merge_requests).to eq(3)
   end
 
   it 'sorts by milestone due soon' do
     visit_merge_requests(project, sort: sort_value_milestone_soon)
 
     expect(first_merge_request).to include('fix')
+    expect(count_merge_requests).to eq(3)
   end
 
   it 'sorts by milestone due later' do
     visit_merge_requests(project, sort: sort_value_milestone_later)
 
     expect(first_merge_request).to include('markdown')
+    expect(count_merge_requests).to eq(3)
   end
 
   it 'filters on one label and sorts by due soon' do
@@ -94,6 +102,7 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
                                   sort: sort_value_due_date_soon)
 
     expect(first_merge_request).to include('fix')
+    expect(count_merge_requests).to eq(1)
   end
 
   context 'while filtering on two labels' do
@@ -110,6 +119,7 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
                                     sort: sort_value_due_date_soon)
 
       expect(first_merge_request).to include('fix')
+      expect(count_merge_requests).to eq(1)
     end
 
     context 'filter on assignee and' do
@@ -119,6 +129,7 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
                                       sort: sort_value_due_date_soon)
 
         expect(first_merge_request).to include('fix')
+        expect(count_merge_requests).to eq(1)
       end
     end
   end
@@ -134,4 +145,8 @@ describe 'Projects > Merge requests > User lists merge requests', feature: true
   def last_merge_request
     page.all('ul.mr-list > li').last.text
   end
+
+  def count_merge_requests
+    page.all('ul.mr-list > li').count
+  end
 end
diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb
index 389812ff7e1c06045ecef26d9e43ce3cdc22aabe..9e9fec01943368eff2ed82ca8473b50bf01110d5 100644
--- a/spec/features/notes_on_merge_requests_spec.rb
+++ b/spec/features/notes_on_merge_requests_spec.rb
@@ -192,7 +192,7 @@ describe 'Comments', feature: true do
         end
 
         it 'should be removed when canceled' do
-          page.within(".diff-file form[id$='#{line_code}']") do
+          page.within(".diff-file form[id$='#{line_code}-true']") do
             find('.js-close-discussion-note-form').trigger('click')
           end
 
diff --git a/spec/features/signup_spec.rb b/spec/features/signup_spec.rb
index 58aabd913ebcb150780c11a7c8f9a906fd22b524..4229e82b4438c5c1aea00153079cf3ef32a5b613 100644
--- a/spec/features/signup_spec.rb
+++ b/spec/features/signup_spec.rb
@@ -2,20 +2,45 @@ require 'spec_helper'
 
 feature 'Signup', feature: true do
   describe 'signup with no errors' do
-    it 'creates the user account and sends a confirmation email' do
-      user = build(:user)
 
-      visit root_path
+    context "when sending confirmation email" do
+      before { allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(true) }
 
-      fill_in 'new_user_name',     with: user.name
-      fill_in 'new_user_username', with: user.username
-      fill_in 'new_user_email',    with: user.email
-      fill_in 'new_user_password', with: user.password
-      click_button "Sign up"
+      it 'creates the user account and sends a confirmation email' do
+        user = build(:user)
+
+        visit root_path
+
+        fill_in 'new_user_name',     with: user.name
+        fill_in 'new_user_username', with: user.username
+        fill_in 'new_user_email',    with: user.email
+        fill_in 'new_user_password', with: user.password
+        click_button "Sign up"
 
-      expect(current_path).to eq users_almost_there_path
-      expect(page).to have_content("Please check your email to confirm your account")
+        expect(current_path).to eq users_almost_there_path
+        expect(page).to have_content("Please check your email to confirm your account")
+      end
     end
+
+    context "when not sending confirmation email" do
+      before { allow_any_instance_of(ApplicationSetting).to receive(:send_user_confirmation_email).and_return(false) }
+
+      it 'creates the user account and goes to dashboard' do
+        user = build(:user)
+
+        visit root_path
+
+        fill_in 'new_user_name',     with: user.name
+        fill_in 'new_user_username', with: user.username
+        fill_in 'new_user_email',    with: user.email
+        fill_in 'new_user_password', with: user.password
+        click_button "Sign up"
+
+        expect(current_path).to eq dashboard_projects_path
+        expect(page).to have_content("Welcome! You have signed up successfully.")
+      end
+    end
+
   end
 
   describe 'signup with errors' do
diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
index bc607a29751d85639ab9c25f981ea8ccd672b465..ec8809e6926c3940f5dba90bc6d6dceaaba2f202 100644
--- a/spec/finders/issues_finder_spec.rb
+++ b/spec/finders/issues_finder_spec.rb
@@ -1,10 +1,10 @@
 require 'spec_helper'
 
 describe IssuesFinder do
-  let(:user) { create :user }
-  let(:user2) { create :user }
-  let(:project1) { create(:project) }
-  let(:project2) { create(:project) }
+  let(:user) { create(:user) }
+  let(:user2) { create(:user) }
+  let(:project1) { create(:empty_project) }
+  let(:project2) { create(:empty_project) }
   let(:milestone) { create(:milestone, project: project1) }
   let(:label) { create(:label, project: project2) }
   let(:issue1) { create(:issue, author: user, assignee: user, project: project1, milestone: milestone) }
@@ -16,101 +16,147 @@ describe IssuesFinder do
     project1.team << [user, :master]
     project2.team << [user, :developer]
     project2.team << [user2, :developer]
+
+    issue1
+    issue2
+    issue3
   end
 
-  describe :execute do
-    before :each do
-      issue1
-      issue2
-      issue3
-    end
+  describe '#execute' do
+    let(:search_user) { user }
+    let(:params) { {} }
+    let(:issues) { IssuesFinder.new(search_user, params.merge(scope: scope, state: 'opened')).execute }
 
     context 'scope: all' do
-      it 'should filter by all' do
-        params = { scope: "all", state: 'opened' }
-        issues = IssuesFinder.new(user, params).execute
-        expect(issues.size).to eq(3)
+      let(:scope) { 'all' }
+
+      it 'returns all issues' do
+        expect(issues).to contain_exactly(issue1, issue2, issue3)
       end
 
-      it 'should filter by assignee id' do
-        params = { scope: "all", assignee_id: user.id, state: 'opened' }
-        issues = IssuesFinder.new(user, params).execute
-        expect(issues.size).to eq(2)
+      context 'filtering by assignee ID' do
+        let(:params) { { assignee_id: user.id } }
+
+        it 'returns issues assigned to that user' do
+          expect(issues).to contain_exactly(issue1, issue2)
+        end
       end
 
-      it 'should filter by author id' do
-        params = { scope: "all", author_id: user2.id, state: 'opened' }
-        issues = IssuesFinder.new(user, params).execute
-        expect(issues).to eq([issue3])
+      context 'filtering by author ID' do
+        let(:params) { { author_id: user2.id } }
+
+        it 'returns issues created by that user' do
+          expect(issues).to contain_exactly(issue3)
+        end
       end
 
-      it 'should filter by milestone id' do
-        params = { scope: "all", milestone_title: milestone.title, state: 'opened' }
-        issues = IssuesFinder.new(user, params).execute
-        expect(issues).to eq([issue1])
+      context 'filtering by milestone' do
+        let(:params) { { milestone_title: milestone.title } }
+
+        it 'returns issues assigned to that milestone' do
+          expect(issues).to contain_exactly(issue1)
+        end
       end
 
-      it 'should filter by no milestone id' do
-        params = { scope: "all", milestone_title: Milestone::None.title, state: 'opened' }
-        issues = IssuesFinder.new(user, params).execute
-        expect(issues).to match_array([issue2, issue3])
+      context 'filtering by no milestone' do
+        let(:params) { { milestone_title: Milestone::None.title } }
+
+        it 'returns issues with no milestone' do
+          expect(issues).to contain_exactly(issue2, issue3)
+        end
       end
 
-      it 'should filter by label name' do
-        params = { scope: "all", label_name: label.title, state: 'opened' }
-        issues = IssuesFinder.new(user, params).execute
-        expect(issues).to eq([issue2])
+      context 'filtering by upcoming milestone' do
+        let(:params) { { milestone_title: Milestone::Upcoming.name } }
+
+        let(:project_no_upcoming_milestones) { create(:empty_project, :public) }
+        let(:project_next_1_1) { create(:empty_project, :public) }
+        let(:project_next_8_8) { create(:empty_project, :public) }
+
+        let(:yesterday) { Date.today - 1.day }
+        let(:tomorrow) { Date.today + 1.day }
+        let(:two_days_from_now) { Date.today + 2.days }
+        let(:ten_days_from_now) { Date.today + 10.days }
+
+        let(:milestones) do
+          [
+            create(:milestone, :closed, project: project_no_upcoming_milestones),
+            create(:milestone, project: project_next_1_1, title: '1.1', due_date: two_days_from_now),
+            create(:milestone, project: project_next_1_1, title: '8.8', due_date: ten_days_from_now),
+            create(:milestone, project: project_next_8_8, title: '1.1', due_date: yesterday),
+            create(:milestone, project: project_next_8_8, title: '8.8', due_date: tomorrow)
+          ]
+        end
+
+        before do
+          milestones.each do |milestone|
+            create(:issue, project: milestone.project, milestone: milestone, author: user, assignee: user)
+          end
+        end
+
+        it 'returns issues in the upcoming milestone for each project' do
+          expect(issues.map { |issue| issue.milestone.title }).to contain_exactly('1.1', '8.8')
+          expect(issues.map { |issue| issue.milestone.due_date }).to contain_exactly(tomorrow, two_days_from_now)
+        end
       end
 
-      it 'returns unique issues when filtering by multiple labels' do
-        label2 = create(:label, project: project2)
+      context 'filtering by label' do
+        let(:params) { { label_name: label.title } }
 
-        create(:label_link, label: label2, target: issue2)
+        it 'returns issues with that label' do
+          expect(issues).to contain_exactly(issue2)
+        end
+      end
 
-        params = {
-          scope:      'all',
-          label_name: [label.title, label2.title].join(','),
-          state:      'opened'
-        }
+      context 'filtering by multiple labels' do
+        let(:params) { { label_name: [label.title, label2.title].join(',') } }
+        let(:label2) { create(:label, project: project2) }
 
-        issues = IssuesFinder.new(user, params).execute
+        before { create(:label_link, label: label2, target: issue2) }
 
-        expect(issues).to eq([issue2])
+        it 'returns the unique issues with any of those labels' do
+          expect(issues).to contain_exactly(issue2)
+        end
       end
 
-      it 'should filter by no label name' do
-        params = { scope: "all", label_name: Label::None.title, state: 'opened' }
-        issues = IssuesFinder.new(user, params).execute
-        expect(issues).to match_array([issue1, issue3])
+      context 'filtering by no label' do
+        let(:params) { { label_name: Label::None.title } }
+
+        it 'returns issues with no labels' do
+          expect(issues).to contain_exactly(issue1, issue3)
+        end
       end
 
-      it 'should be empty for unauthorized user' do
-        params = { scope: "all", state: 'opened' }
-        issues = IssuesFinder.new(nil, params).execute
-        expect(issues.size).to be_zero
+      context 'when the user is unauthorized' do
+        let(:search_user) { nil }
+
+        it 'returns no results' do
+          expect(issues).to be_empty
+        end
       end
 
-      it 'should not include unauthorized issues' do
-        params = { scope: "all", state: 'opened' }
-        issues = IssuesFinder.new(user2, params).execute
-        expect(issues.size).to eq(2)
-        expect(issues).not_to include(issue1)
-        expect(issues).to include(issue2)
-        expect(issues).to include(issue3)
+      context 'when the user can see some, but not all, issues' do
+        let(:search_user) { user2 }
+
+        it 'returns only issues they can see' do
+          expect(issues).to contain_exactly(issue2, issue3)
+        end
       end
     end
 
     context 'personal scope' do
-      it 'should filter by assignee' do
-        params = { scope: "assigned-to-me", state: 'opened' }
-        issues = IssuesFinder.new(user, params).execute
-        expect(issues.size).to eq(2)
+      let(:scope) { 'assigned-to-me' }
+
+      it 'returns issue assigned to the user' do
+        expect(issues).to contain_exactly(issue1, issue2)
       end
 
-      it 'should filter by project' do
-        params = { scope: "assigned-to-me", state: 'opened', project_id: project1.id }
-        issues = IssuesFinder.new(user, params).execute
-        expect(issues.size).to eq(1)
+      context 'filtering by project' do
+        let(:params) { { project_id: project1.id } }
+
+        it 'returns issues assigned to the user in that project' do
+          expect(issues).to contain_exactly(issue1)
+        end
       end
     end
   end
diff --git a/spec/lib/gitlab/github_import/branch_formatter_spec.rb b/spec/lib/gitlab/github_import/branch_formatter_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3cb634ba010bb57d5cdedeaeab4587328c0dc638
--- /dev/null
+++ b/spec/lib/gitlab/github_import/branch_formatter_spec.rb
@@ -0,0 +1,71 @@
+require 'spec_helper'
+
+describe Gitlab::GithubImport::BranchFormatter, lib: true do
+  let(:project) { create(:project) }
+  let(:repo) { double }
+  let(:raw) do
+    {
+      ref: 'feature',
+      repo: repo,
+      sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b'
+    }
+  end
+
+  describe '#exists?' do
+    it 'returns true when branch exists' do
+      branch = described_class.new(project, double(raw))
+
+      expect(branch.exists?).to eq true
+    end
+
+    it 'returns false when branch does not exist' do
+      branch = described_class.new(project, double(raw.merge(ref: 'removed-branch')))
+
+      expect(branch.exists?).to eq false
+    end
+  end
+
+  describe '#name' do
+    it 'returns raw ref when branch exists' do
+      branch = described_class.new(project, double(raw))
+
+      expect(branch.name).to eq 'feature'
+    end
+
+    it 'returns formatted ref when branch does not exist' do
+      branch = described_class.new(project, double(raw.merge(ref: 'removed-branch')))
+
+      expect(branch.name).to eq 'removed-branch-2e5d3239'
+    end
+  end
+
+  describe '#repo' do
+    it 'returns raw repo' do
+      branch = described_class.new(project, double(raw))
+
+      expect(branch.repo).to eq repo
+    end
+  end
+
+  describe '#sha' do
+    it 'returns raw sha' do
+      branch = described_class.new(project, double(raw))
+
+      expect(branch.sha).to eq '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b'
+    end
+  end
+
+  describe '#valid?' do
+    it 'returns true when repository exists' do
+      branch = described_class.new(project, double(raw))
+
+      expect(branch.valid?).to eq true
+    end
+
+    it 'returns false when repository does not exist' do
+      branch = described_class.new(project, double(raw.merge(repo: nil)))
+
+      expect(branch.valid?).to eq false
+    end
+  end
+end
diff --git a/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb b/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb
index e59c0ca110e66b35cc16c59601892cf78e041025..120f59e6e71fd41a926d0dd66efaa64647d01b86 100644
--- a/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb
+++ b/spec/lib/gitlab/github_import/pull_request_formatter_spec.rb
@@ -4,9 +4,9 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
   let(:project) { create(:project) }
   let(:repository) { double(id: 1, fork: false) }
   let(:source_repo) { repository }
-  let(:source_branch) { double(ref: 'feature', repo: source_repo) }
+  let(:source_branch) { double(ref: 'feature', repo: source_repo, sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b') }
   let(:target_repo) { repository }
-  let(:target_branch) { double(ref: 'master', repo: target_repo) }
+  let(:target_branch) { double(ref: 'master', repo: target_repo, sha: '8ffb3c15a5475e59ae909384297fede4badcb4c7') }
   let(:octocat) { double(id: 123456, login: 'octocat') }
   let(:created_at) { DateTime.strptime('2011-01-26T19:01:12Z') }
   let(:updated_at) { DateTime.strptime('2011-01-27T19:01:12Z') }
@@ -41,8 +41,10 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
           description: "*Created by: octocat*\n\nPlease pull these awesome changes",
           source_project: project,
           source_branch: 'feature',
+          head_source_sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b',
           target_project: project,
           target_branch: 'master',
+          base_target_sha: '8ffb3c15a5475e59ae909384297fede4badcb4c7',
           state: 'opened',
           milestone: nil,
           author_id: project.creator_id,
@@ -66,8 +68,10 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
           description: "*Created by: octocat*\n\nPlease pull these awesome changes",
           source_project: project,
           source_branch: 'feature',
+          head_source_sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b',
           target_project: project,
           target_branch: 'master',
+          base_target_sha: '8ffb3c15a5475e59ae909384297fede4badcb4c7',
           state: 'closed',
           milestone: nil,
           author_id: project.creator_id,
@@ -91,8 +95,10 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
           description: "*Created by: octocat*\n\nPlease pull these awesome changes",
           source_project: project,
           source_branch: 'feature',
+          head_source_sha: '2e5d3239642f9161dcbbc4b70a211a68e5e45e2b',
           target_project: project,
           target_branch: 'master',
+          base_target_sha: '8ffb3c15a5475e59ae909384297fede4badcb4c7',
           state: 'merged',
           milestone: nil,
           author_id: project.creator_id,
@@ -137,11 +143,11 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
       let(:milestone) { double(number: 45) }
       let(:raw_data) { double(base_data.merge(milestone: milestone)) }
 
-      it 'returns nil when milestone does not exists' do
+      it 'returns nil when milestone does not exist' do
         expect(pull_request.attributes.fetch(:milestone)).to be_nil
       end
 
-      it 'returns milestone when is exists' do
+      it 'returns milestone when it exists' do
         milestone = create(:milestone, project: project, iid: 45)
 
         expect(pull_request.attributes.fetch(:milestone)).to eq milestone
@@ -158,36 +164,16 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
   end
 
   describe '#valid?' do
-    let(:invalid_branch) { double(ref: 'invalid-branch').as_null_object }
-
-    context 'when source, and target repositories are the same' do
-      context 'and source and target branches exists' do
-        let(:raw_data) { double(base_data.merge(head: source_branch, base: target_branch)) }
-
-        it 'returns true' do
-          expect(pull_request.valid?).to eq true
-        end
-      end
-
-      context 'and source branch doesn not exists' do
-        let(:raw_data) { double(base_data.merge(head: invalid_branch, base: target_branch)) }
-
-        it 'returns false' do
-          expect(pull_request.valid?).to eq false
-        end
-      end
-
-      context 'and target branch doesn not exists' do
-        let(:raw_data) { double(base_data.merge(head: source_branch, base: invalid_branch)) }
+    context 'when source, and target repos are not a fork' do
+      let(:raw_data) { double(base_data) }
 
-        it 'returns false' do
-          expect(pull_request.valid?).to eq false
-        end
+      it 'returns true' do
+        expect(pull_request.valid?).to eq true
       end
     end
 
     context 'when source repo is a fork' do
-      let(:source_repo) { double(id: 2, fork: true) }
+      let(:source_repo) { double(id: 2) }
       let(:raw_data) { double(base_data) }
 
       it 'returns false' do
@@ -196,7 +182,7 @@ describe Gitlab::GithubImport::PullRequestFormatter, lib: true do
     end
 
     context 'when target repo is a fork' do
-      let(:target_repo) { double(id: 2, fork: true) }
+      let(:target_repo) { double(id: 2) }
       let(:raw_data) { double(base_data) }
 
       it 'returns false' do
diff --git a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
index e01b0b4bd21b1e89f6f47761e53afded2ae43caf..d824dc54438bb1453aab68d2b53650239a127802 100644
--- a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
@@ -9,7 +9,7 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
   describe '#cache_read' do
     it 'increments the cache_read duration' do
       expect(subscriber).to receive(:increment).
-        with(:cache_read_duration, event.duration)
+        with(:cache_read, event.duration)
 
       subscriber.cache_read(event)
     end
@@ -18,7 +18,7 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
   describe '#cache_write' do
     it 'increments the cache_write duration' do
       expect(subscriber).to receive(:increment).
-        with(:cache_write_duration, event.duration)
+        with(:cache_write, event.duration)
 
       subscriber.cache_write(event)
     end
@@ -27,7 +27,7 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
   describe '#cache_delete' do
     it 'increments the cache_delete duration' do
       expect(subscriber).to receive(:increment).
-        with(:cache_delete_duration, event.duration)
+        with(:cache_delete, event.duration)
 
       subscriber.cache_delete(event)
     end
@@ -36,7 +36,7 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
   describe '#cache_exist?' do
     it 'increments the cache_exists duration' do
       expect(subscriber).to receive(:increment).
-        with(:cache_exists_duration, event.duration)
+        with(:cache_exists, event.duration)
 
       subscriber.cache_exist?(event)
     end
@@ -61,10 +61,16 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
         expect(transaction).to receive(:increment).
           with(:cache_duration, event.duration)
 
+        expect(transaction).to receive(:increment).
+          with(:cache_count, 1)
+
         expect(transaction).to receive(:increment).
           with(:cache_delete_duration, event.duration)
 
-        subscriber.increment(:cache_delete_duration, event.duration)
+        expect(transaction).to receive(:increment).
+          with(:cache_delete_count, 1)
+
+        subscriber.increment(:cache_delete, event.duration)
       end
     end
   end
diff --git a/spec/models/legacy_diff_note_spec.rb b/spec/models/legacy_diff_note_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7c29bef54e48b8993c02d7f32e04eaccfeceddc2
--- /dev/null
+++ b/spec/models/legacy_diff_note_spec.rb
@@ -0,0 +1,74 @@
+require 'spec_helper'
+
+describe LegacyDiffNote, models: true do
+  describe "Commit diff line notes" do
+    let!(:note) { create(:note_on_commit_diff, note: "+1 from me") }
+    let!(:commit) { note.noteable }
+
+    it "should save a valid note" do
+      expect(note.commit_id).to eq(commit.id)
+      expect(note.noteable.id).to eq(commit.id)
+    end
+
+    it "should be recognized by #legacy_diff_note?" do
+      expect(note).to be_legacy_diff_note
+    end
+  end
+
+  describe '#active?' do
+    it 'is always true when the note has no associated diff' do
+      note = build(:note_on_merge_request_diff)
+
+      expect(note).to receive(:diff).and_return(nil)
+
+      expect(note).to be_active
+    end
+
+    it 'is never true when the note has no noteable associated' do
+      note = build(:note_on_merge_request_diff)
+
+      expect(note).to receive(:diff).and_return(double)
+      expect(note).to receive(:noteable).and_return(nil)
+
+      expect(note).not_to be_active
+    end
+
+    it 'returns the memoized value if defined' do
+      note = build(:note_on_merge_request_diff)
+
+      note.instance_variable_set(:@active, 'foo')
+      expect(note).not_to receive(:find_noteable_diff)
+
+      expect(note.active?).to eq 'foo'
+    end
+
+    context 'for a merge request noteable' do
+      it 'is false when noteable has no matching diff' do
+        merge = build_stubbed(:merge_request, :simple)
+        note = build(:note_on_merge_request_diff, noteable: merge)
+
+        allow(note).to receive(:diff).and_return(double)
+        expect(note).to receive(:find_noteable_diff).and_return(nil)
+
+        expect(note).not_to be_active
+      end
+
+      it 'is true when noteable has a matching diff' do
+        merge = create(:merge_request, :simple)
+
+        # Generate a real line_code value so we know it will match. We use a
+        # random line from a random diff just for funsies.
+        diff = merge.diffs.to_a.sample
+        line = Gitlab::Diff::Parser.new.parse(diff.diff.each_line).to_a.sample
+        code = Gitlab::Diff::LineCode.generate(diff.new_path, line.new_pos, line.old_pos)
+
+        # We're persisting in order to trigger the set_diff callback
+        note = create(:note_on_merge_request_diff, noteable: merge, line_code: code)
+
+        # Make sure we don't get a false positive from a guard clause
+        expect(note).to receive(:find_noteable_diff).and_call_original
+        expect(note).to be_active
+      end
+    end
+  end
+end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index c8578749b211613562e209690992a4aba1e54c76..9eef08c6d00a7aa0dcf58f4aaf6e54106fa8d57c 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -64,7 +64,13 @@ describe MergeRequest, models: true do
 
   describe '#target_sha' do
     context 'when the target branch does not exist anymore' do
-      subject { create(:merge_request).tap { |mr| mr.update_attribute(:target_branch, 'deleted') } }
+      let(:project) { create(:project) }
+
+      subject { create(:merge_request, source_project: project, target_project: project) }
+
+      before do
+        project.repository.raw_repository.delete_branch(subject.target_branch)
+      end
 
       it 'returns nil' do
         expect(subject.target_sha).to be_nil
@@ -289,7 +295,12 @@ describe MergeRequest, models: true do
     let(:fork_project) { create(:project, forked_from_project: project) }
 
     context 'when the target branch does not exist anymore' do
-      subject { create(:merge_request).tap { |mr| mr.update_attribute(:target_branch, 'deleted') } }
+      subject { create(:merge_request, source_project: project, target_project: project) }
+
+      before do
+        project.repository.raw_repository.delete_branch(subject.target_branch)
+        subject.reload
+      end
 
       it 'does not crash' do
         expect{ subject.diverged_commits_count }.not_to raise_error
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index 247a9fa9910a9a013332fde277bc4a4c4232b8da..1e18c788b503d0c48f306bda2b05cb02fb9fb285 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -204,4 +204,37 @@ describe Milestone, models: true do
         to eq([milestone])
     end
   end
+
+  describe '.upcoming_ids_by_projects' do
+    let(:project_1) { create(:empty_project) }
+    let(:project_2) { create(:empty_project) }
+    let(:project_3) { create(:empty_project) }
+    let(:projects) { [project_1, project_2, project_3] }
+
+    let!(:past_milestone_project_1) { create(:milestone, project: project_1, due_date: Time.now - 1.day) }
+    let!(:current_milestone_project_1) { create(:milestone, project: project_1, due_date: Time.now + 1.day) }
+    let!(:future_milestone_project_1) { create(:milestone, project: project_1, due_date: Time.now + 2.days) }
+
+    let!(:past_milestone_project_2) { create(:milestone, project: project_2, due_date: Time.now - 1.day) }
+    let!(:closed_milestone_project_2) { create(:milestone, :closed, project: project_2, due_date: Time.now + 1.day) }
+    let!(:current_milestone_project_2) { create(:milestone, project: project_2, due_date: Time.now + 2.days) }
+
+    let!(:past_milestone_project_3) { create(:milestone, project: project_3, due_date: Time.now - 1.day) }
+
+    # The call to `#try` is because this returns a relation with a Postgres DB,
+    # and an array of IDs with a MySQL DB.
+    let(:milestone_ids) { Milestone.upcoming_ids_by_projects(projects).map { |id| id.try(:id) || id } }
+
+    it 'returns the next upcoming open milestone ID for each project' do
+      expect(milestone_ids).to contain_exactly(current_milestone_project_1.id, current_milestone_project_2.id)
+    end
+
+    context 'when the projects have no open upcoming milestones' do
+      let(:projects) { [project_3] }
+
+      it 'returns no results' do
+        expect(milestone_ids).to be_empty
+      end
+    end
+  end
 end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 4b788b578829788735ccbcd76fc518f90a05e131..5d916f0e6a65b2263cb506f583e033438d2f7436 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -34,24 +34,6 @@ describe Note, models: true do
     end
   end
 
-  describe "Commit diff line notes" do
-    let!(:note) { create(:note_on_commit_diff, note: "+1 from me") }
-    let!(:commit) { note.noteable }
-
-    it "should save a valid note" do
-      expect(note.commit_id).to eq(commit.id)
-      expect(note.noteable.id).to eq(commit.id)
-    end
-
-    it "should be recognized by #for_diff_line?" do
-      expect(note).to be_for_diff_line
-    end
-
-    it "should be recognized by #for_commit_diff_line?" do
-      expect(note).to be_for_commit_diff_line
-    end
-  end
-
   describe 'authorization' do
     before do
       @p1 = create(:project)
@@ -148,66 +130,6 @@ describe Note, models: true do
     end
   end
 
-  describe '#active?' do
-    it 'is always true when the note has no associated diff' do
-      note = build(:note)
-
-      expect(note).to receive(:diff).and_return(nil)
-
-      expect(note).to be_active
-    end
-
-    it 'is never true when the note has no noteable associated' do
-      note = build(:note)
-
-      expect(note).to receive(:diff).and_return(double)
-      expect(note).to receive(:noteable).and_return(nil)
-
-      expect(note).not_to be_active
-    end
-
-    it 'returns the memoized value if defined' do
-      note = build(:note)
-
-      expect(note).to receive(:diff).and_return(double)
-      expect(note).to receive(:noteable).and_return(double)
-
-      note.instance_variable_set(:@active, 'foo')
-      expect(note).not_to receive(:find_noteable_diff)
-
-      expect(note.active?).to eq 'foo'
-    end
-
-    context 'for a merge request noteable' do
-      it 'is false when noteable has no matching diff' do
-        merge = build_stubbed(:merge_request, :simple)
-        note = build(:note, noteable: merge)
-
-        allow(note).to receive(:diff).and_return(double)
-        expect(note).to receive(:find_noteable_diff).and_return(nil)
-
-        expect(note).not_to be_active
-      end
-
-      it 'is true when noteable has a matching diff' do
-        merge = create(:merge_request, :simple)
-
-        # Generate a real line_code value so we know it will match. We use a
-        # random line from a random diff just for funsies.
-        diff = merge.diffs.to_a.sample
-        line = Gitlab::Diff::Parser.new.parse(diff.diff.each_line).to_a.sample
-        code = Gitlab::Diff::LineCode.generate(diff.new_path, line.new_pos, line.old_pos)
-
-        # We're persisting in order to trigger the set_diff callback
-        note = create(:note, noteable: merge, line_code: code)
-
-        # Make sure we don't get a false positive from a guard clause
-        expect(note).to receive(:find_noteable_diff).and_call_original
-        expect(note).to be_active
-      end
-    end
-  end
-
   describe "editable?" do
     it "returns true" do
       note = build(:note)
@@ -258,7 +180,7 @@ describe Note, models: true do
     end
 
     it "is not an award emoji when comment is on a diff" do
-      note = create(:note, note: ":blowfish:", noteable: merge_request, line_code: "11d5d2e667e9da4f7f610f81d86c974b146b13bd_0_2")
+      note = create(:note_on_merge_request_diff, note: ":blowfish:", noteable: merge_request, line_code: "11d5d2e667e9da4f7f610f81d86c974b146b13bd_0_2")
       note = note.reload
 
       expect(note.note).to eq(":blowfish:")
diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb
index 532e3f013fd0aa692d77e84ba88c37d753c757f6..91ebb612baaf5881a0caf89a9c1776f19de486c5 100644
--- a/spec/models/project_wiki_spec.rb
+++ b/spec/models/project_wiki_spec.rb
@@ -38,7 +38,8 @@ describe ProjectWiki, models: true do
 
   describe "#wiki_base_path" do
     it "returns the wiki base path" do
-      wiki_base_path = "/#{project.path_with_namespace}/wikis"
+      wiki_base_path = "#{Gitlab.config.gitlab.relative_url_root}/#{project.path_with_namespace}/wikis"
+
       expect(subject.wiki_base_path).to eq(wiki_base_path)
     end
   end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 10e7e693571825376ca65860cbcc52432c03b7d9..9581990666b1a95d2bd8920c7e21b25855a4283d 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -141,6 +141,7 @@ describe User, models: true do
   end
 
   describe '#confirm' do
+    before { allow(current_application_settings).to receive(:send_user_confirmation_email).and_return(true) }
     let(:user) { create(:user, confirmed_at: nil, unconfirmed_email: 'test@gitlab.com') }
 
     it 'returns unconfirmed' do