diff --git a/CHANGELOG b/CHANGELOG
index 43302425f14b73c54a0404dc338a73a92d59caa6..54f83e5aeac8be0545650e497935d5edeff54442 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,13 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
+v 8.0.0 (unreleased)
+  - Remove satellites
+  - Better performance for web editor (switched from satellites to rugged)
+  - Faster merge
+  - Ability to fetch merge requests from refs/merge-requests/:id
+  - Allow displaying of archived projects in the admin interface (Artem Sidorenko)
+  - Allow configuration of import sources for new projects (Artem Sidorenko)
+
 v 7.14.0 (unreleased)
   - Update default robots.txt rules to disallow crawling of irrelevant pages (Ben Bodenmiller)
   - Fix redirection after sign in when using auto_sign_in_with_provider
diff --git a/VERSION b/VERSION
index da8322eb293f8f754dd0e64a7f9cbaf9fcf8a1d1..939cbc3ea745c36481e91417ddd41ee4d7c21774 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-7.14.0.pre
+8.0.0.pre
diff --git a/app/assets/javascripts/merge_request_widget.js.coffee b/app/assets/javascripts/merge_request_widget.js.coffee
index 5ab91261d75d8c8ce7f2d12dbadd3825da20ca58..995a2f24093357901806713a49774fdb2d3018bb 100644
--- a/app/assets/javascripts/merge_request_widget.js.coffee
+++ b/app/assets/javascripts/merge_request_widget.js.coffee
@@ -19,7 +19,7 @@ class @MergeRequestWidget
           when 'merged'
             location.reload()
           else
-            setTimeout(merge_request_widget.mergeInProgress, 3000)
+            setTimeout(merge_request_widget.mergeInProgress, 2000)
       dataType: 'json'
 
   getMergeStatus: ->
diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss
index d36530169a915b5848635119143da3be302a6f3b..bf5c7a8d75ebbeb7cd099dc5794e33906fb0a85f 100644
--- a/app/assets/stylesheets/generic/common.scss
+++ b/app/assets/stylesheets/generic/common.scss
@@ -373,3 +373,23 @@ table {
     border-color: #EEE !important;
   }
 }
+
+.center-top-menu {
+  border-bottom: 1px solid #EEE;
+  list-style: none;
+  text-align: center;
+  padding-bottom: 15px;
+  margin-bottom: 15px;
+
+  li {
+    display: inline-block;
+
+    a {
+      padding: 10px;
+    }
+
+    &.active a {
+      color: #666;
+    }
+  }
+}
diff --git a/app/assets/stylesheets/pages/explore.scss b/app/assets/stylesheets/pages/explore.scss
index 9b92128624c1053661040c1b2c6f2abc4d295f2c..da06fe9954e018e6c2d928a824037c542e8cdb91 100644
--- a/app/assets/stylesheets/pages/explore.scss
+++ b/app/assets/stylesheets/pages/explore.scss
@@ -6,3 +6,11 @@
     font-size: 30px;
   }
 }
+
+.explore-trending-block {
+  .lead {
+    line-height: 32px;
+    font-size: 18px;
+    margin-top: 10px;
+  }
+}
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index c7c643db4010d398a93d21c8250ef1110b688822..f38e07af84b1a9a83f6440f10c432f42fc5e43ef 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -29,6 +29,15 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
       end
     end
 
+    import_sources = params[:application_setting][:import_sources]
+    if import_sources.nil?
+      params[:application_setting][:import_sources] = []
+    else
+      import_sources.map! do |source|
+        source.to_str
+      end
+    end
+
     params.require(:application_setting).permit(
       :default_projects_limit,
       :default_branch_protection,
@@ -47,6 +56,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
       :version_check_enabled,
       :user_oauth_applications,
       restricted_visibility_levels: [],
+      import_sources: []
     )
   end
 end
diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb
index da5f5bb83fa1afd3e8f561173b44b3e09e1c1eff..ae1de06b983ce58ba5690eaa83b553eee03d56bf 100644
--- a/app/controllers/admin/projects_controller.rb
+++ b/app/controllers/admin/projects_controller.rb
@@ -9,6 +9,7 @@ class Admin::ProjectsController < Admin::ApplicationController
     @projects = @projects.where("visibility_level IN (?)", params[:visibility_levels]) if params[:visibility_levels].present?
     @projects = @projects.with_push if params[:with_push].present?
     @projects = @projects.abandoned if params[:abandoned].present?
+    @projects = @projects.non_archived unless params[:with_archived].present?
     @projects = @projects.search(params[:name]) if params[:name].present?
     @projects = @projects.sort(@sort = params[:sort])
     @projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(PER_PAGE)
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 3ce8dbc9407d45a572ca96572202206b27e326f9..12d439b0b312b4775d13319a8aebcd4106b3241f 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -20,7 +20,7 @@ class ApplicationController < ActionController::Base
   protect_from_forgery with: :exception
 
   helper_method :abilities, :can?, :current_application_settings
-  helper_method :github_import_enabled?, :gitlab_import_enabled?, :bitbucket_import_enabled?
+  helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :git_import_enabled?
 
   rescue_from Encoding::CompatibilityError do |exception|
     log_exception(exception)
@@ -298,15 +298,43 @@ class ApplicationController < ActionController::Base
     @issuable_finder.execute
   end
 
+  def import_sources_enabled?
+    !current_application_settings.import_sources.empty?
+  end
+
   def github_import_enabled?
+    current_application_settings.import_sources.include?('github')
+  end
+
+  def github_import_configured?
     Gitlab::OAuth::Provider.enabled?(:github)
   end
 
   def gitlab_import_enabled?
+    request.host != 'gitlab.com' && current_application_settings.import_sources.include?('gitlab')
+  end
+
+  def gitlab_import_configured?
     Gitlab::OAuth::Provider.enabled?(:gitlab)
   end
 
   def bitbucket_import_enabled?
+    current_application_settings.import_sources.include?('bitbucket')
+  end
+
+  def bitbucket_import_configured?
     Gitlab::OAuth::Provider.enabled?(:bitbucket) && Gitlab::BitbucketImport.public_key.present?
   end
+
+  def gitorious_import_enabled?
+    current_application_settings.import_sources.include?('gitorious')
+  end
+
+  def google_code_import_enabled?
+    current_application_settings.import_sources.include?('google_code')
+  end
+
+  def git_import_enabled?
+    current_application_settings.import_sources.include?('git')
+  end
 end
diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb
index e9bcb44f6b3967489443f96cc477a7560890217f..6c733c1ae4d54121199ef81f6a3a42a5438a373e 100644
--- a/app/controllers/explore/projects_controller.rb
+++ b/app/controllers/explore/projects_controller.rb
@@ -7,6 +7,7 @@ class Explore::ProjectsController < Explore::ApplicationController
     @tags = @projects.tags_on(:tags)
     @projects = @projects.tagged_with(params[:tag]) if params[:tag].present?
     @projects = @projects.where(visibility_level: params[:visibility_level]) if params[:visibility_level].present?
+    @projects = @projects.non_archived
     @projects = @projects.search(params[:search]) if params[:search].present?
     @projects = @projects.sort(@sort = params[:sort])
     @projects = @projects.includes(:namespace).page(params[:page]).per(PER_PAGE)
@@ -14,6 +15,7 @@ class Explore::ProjectsController < Explore::ApplicationController
 
   def trending
     @trending_projects = TrendingProjectsFinder.new.execute(current_user)
+    @trending_projects = @trending_projects.non_archived
     @trending_projects = @trending_projects.page(params[:page]).per(PER_PAGE)
   end
 
diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb
index 8a45dc8860d15f20b40299edd95e90186fc482f7..71831c5380d4ebf2be4610caaffe8ade9af394da 100644
--- a/app/controllers/help_controller.rb
+++ b/app/controllers/help_controller.rb
@@ -10,7 +10,8 @@ class HelpController < ApplicationController
 
     respond_to do |format|
       format.any(:markdown, :md, :html) do
-        path = Rails.root.join('doc', @category, "#{@file}.md")
+        # Note: We are purposefully NOT using `Rails.root.join`
+        path = File.join(Rails.root, 'doc', @category, "#{@file}.md")
 
         if File.exist?(path)
           @markdown = File.read(path)
@@ -24,7 +25,8 @@ class HelpController < ApplicationController
 
       # Allow access to images in the doc folder
       format.any(:png, :gif, :jpeg) do
-        path = Rails.root.join('doc', @category, "#{@file}.#{params[:format]}")
+        # Note: We are purposefully NOT using `Rails.root.join`
+        path = File.join(Rails.root, 'doc', @category, "#{@file}.#{params[:format]}")
 
         if File.exist?(path)
           send_file(path, disposition: 'inline')
diff --git a/app/controllers/import/gitorious_controller.rb b/app/controllers/import/gitorious_controller.rb
index c121d2de7cb65c4732e769355b0018826c28dd25..f24cdb3709a0246eac25ef0c3807d6ebf9b170a2 100644
--- a/app/controllers/import/gitorious_controller.rb
+++ b/app/controllers/import/gitorious_controller.rb
@@ -1,4 +1,5 @@
 class Import::GitoriousController < Import::BaseController
+  before_action :verify_gitorious_import_enabled
 
   def new
     redirect_to client.authorize_url(callback_import_gitorious_url)
@@ -40,4 +41,8 @@ class Import::GitoriousController < Import::BaseController
     @client ||= Gitlab::GitoriousImport::Client.new(session[:gitorious_repos])
   end
 
+  def verify_gitorious_import_enabled
+    not_found! unless gitorious_import_enabled?
+  end
+
 end
diff --git a/app/controllers/import/google_code_controller.rb b/app/controllers/import/google_code_controller.rb
index 4aa6d28c9a803a9e875123b3ea3edcc3f1e64e9b..82fadeb7e832deba7f88860e3db3dd9a0e9cb9b4 100644
--- a/app/controllers/import/google_code_controller.rb
+++ b/app/controllers/import/google_code_controller.rb
@@ -1,4 +1,5 @@
 class Import::GoogleCodeController < Import::BaseController
+  before_action :verify_google_code_import_enabled
   before_action :user_map, only: [:new_user_map, :create_user_map]
 
   def new
@@ -104,6 +105,10 @@ class Import::GoogleCodeController < Import::BaseController
     @client ||= Gitlab::GoogleCodeImport::Client.new(session[:google_code_dump])
   end
 
+  def verify_google_code_import_enabled
+    not_found! unless google_code_import_enabled?
+  end
+
   def user_map
     @user_map ||= begin
       user_map = client.user_map
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index b762518d377fb5dc2ab6670b53f8d3513b4a6e56..100d3d3b3174d3e5103f13090281f5e415e83818 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -13,27 +13,20 @@ class Projects::BlobController < Projects::ApplicationController
   before_action :commit, except: [:new, :create]
   before_action :blob, except: [:new, :create]
   before_action :from_merge_request, only: [:edit, :update]
-  before_action :after_edit_path, only: [:edit, :update]
   before_action :require_branch_head, only: [:edit, :update]
+  before_action :editor_variables, except: [:show, :preview, :diff]
+  before_action :after_edit_path, only: [:edit, :update]
 
   def new
     commit unless @repository.empty?
   end
 
   def create
-    file_path = File.join(@path, File.basename(params[:file_name]))
-    result = Files::CreateService.new(
-      @project,
-      current_user,
-      params.merge(new_branch: sanitized_new_branch_name),
-      @ref,
-      file_path
-    ).execute
+    result = Files::CreateService.new(@project, current_user, @commit_params).execute
 
     if result[:status] == :success
       flash[:notice] = "Your changes have been successfully committed"
-      ref = sanitized_new_branch_name.presence || @ref
-      redirect_to namespace_project_blob_path(@project.namespace, @project, File.join(ref, file_path))
+      redirect_to namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @file_path))
     else
       flash[:alert] = result[:message]
       render :new
@@ -48,22 +41,10 @@ class Projects::BlobController < Projects::ApplicationController
   end
 
   def update
-    result = Files::UpdateService.
-      new(
-        @project,
-        current_user,
-        params.merge(new_branch: sanitized_new_branch_name),
-        @ref,
-        @path
-      ).execute
+    result = Files::UpdateService.new(@project, current_user, @commit_params).execute
 
     if result[:status] == :success
       flash[:notice] = "Your changes have been successfully committed"
-
-      if from_merge_request
-        from_merge_request.reload_code
-      end
-
       redirect_to after_edit_path
     else
       flash[:alert] = result[:message]
@@ -80,12 +61,11 @@ class Projects::BlobController < Projects::ApplicationController
   end
 
   def destroy
-    result = Files::DeleteService.new(@project, current_user, params, @ref, @path).execute
+    result = Files::DeleteService.new(@project, current_user, @commit_params).execute
 
     if result[:status] == :success
       flash[:notice] = "Your changes have been successfully committed"
-      redirect_to namespace_project_tree_path(@project.namespace, @project,
-                                              @ref)
+      redirect_to namespace_project_tree_path(@project.namespace, @project, @target_branch)
     else
       flash[:alert] = result[:message]
       render :show
@@ -135,7 +115,6 @@ class Projects::BlobController < Projects::ApplicationController
     @id = params[:id]
     @ref, @path = extract_ref(@id)
 
-
   rescue InvalidPathError
     not_found!
   end
@@ -145,8 +124,8 @@ class Projects::BlobController < Projects::ApplicationController
       if from_merge_request
         diffs_namespace_project_merge_request_path(from_merge_request.target_project.namespace, from_merge_request.target_project, from_merge_request) +
           "#file-path-#{hexdigest(@path)}"
-      elsif sanitized_new_branch_name.present?
-        namespace_project_blob_path(@project.namespace, @project, File.join(sanitized_new_branch_name, @path))
+      elsif @target_branch.present?
+        namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @path))
       else
         namespace_project_blob_path(@project.namespace, @project, @id)
       end
@@ -160,4 +139,25 @@ class Projects::BlobController < Projects::ApplicationController
   def sanitized_new_branch_name
     @new_branch ||= sanitize(strip_tags(params[:new_branch]))
   end
+
+  def editor_variables
+    @current_branch = @ref
+    @target_branch = (sanitized_new_branch_name || @ref)
+
+    @file_path =
+      if action_name.to_s == 'create'
+        File.join(@path, File.basename(params[:file_name]))
+      else
+        @path
+      end
+
+    @commit_params = {
+      file_path: @file_path,
+      current_branch: @current_branch,
+      target_branch: @target_branch,
+      commit_message: params[:commit_message],
+      file_content: params[:content],
+      file_content_encoding: params[:encoding]
+    }
+  end
 end
diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb
index c5f085c236f70d4acb35f4d9a92d77130f7fb870..d9b3adae95b28cdf34fe77771a5b5d277ac411d3 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -13,13 +13,8 @@ class Projects::CompareController < Projects::ApplicationController
     base_ref = Addressable::URI.unescape(params[:from])
     @ref = head_ref = Addressable::URI.unescape(params[:to])
 
-    compare_result = CompareService.new.execute(
-      current_user,
-      @project,
-      head_ref,
-      @project,
-      base_ref
-    )
+    compare_result = CompareService.new.
+      execute(@project, head_ref, @project, base_ref)
 
     @commits = compare_result.commits
     @diffs = compare_result.diffs
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index d12651983187b65eb4a14e88704a1ea49a33b332..f3054881dafd02d41bdbac7c92b6d08df802524f 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -1,9 +1,7 @@
-require 'gitlab/satellite/satellite'
-
 class Projects::MergeRequestsController < Projects::ApplicationController
   before_action :module_enabled
   before_action :merge_request, only: [
-    :edit, :update, :show, :diffs, :commits, :automerge, :automerge_check,
+    :edit, :update, :show, :diffs, :commits, :merge, :merge_check,
     :ci_status, :toggle_subscription
   ]
   before_action :closes_issues, only: [:edit, :update, :show, :diffs, :commits]
@@ -137,7 +135,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     end
   end
 
-  def automerge_check
+  def merge_check
     if @merge_request.unchecked?
       @merge_request.check_if_can_be_merged
     end
@@ -147,11 +145,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     render partial: "projects/merge_requests/widget/show.html.haml", layout: false
   end
 
-  def automerge
+  def merge
     return access_denied! unless @merge_request.can_be_merged_by?(current_user)
 
-    if @merge_request.automergeable?
-      AutoMergeWorker.perform_async(@merge_request.id, current_user.id, params)
+    if @merge_request.mergeable?
+      MergeWorker.perform_async(@merge_request.id, current_user.id, params)
       @status = true
     else
       @status = false
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 61d14383945018672afa549a3313e5a9e4acc77f..7d6b58ee21a0f74cf87fd245b01fad91b0ae0983 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -39,4 +39,21 @@ module ApplicationSettingsHelper
       end
     end
   end
+
+  # Return a group of checkboxes that use Bootstrap's button plugin for a
+  # toggle button effect.
+  def import_sources_checkboxes(help_block_id)
+    Gitlab::ImportSources.options.map do |name, source|
+      checked = current_application_settings.import_sources.include?(source)
+      css_class = 'btn'
+      css_class += ' active' if checked
+      checkbox_name = 'application_setting[import_sources][]'
+
+      label_tag(checkbox_name, class: css_class) do
+        check_box_tag(checkbox_name, source, checked,
+                      autocomplete: 'off',
+                      'aria-describedby' => help_block_id) + name
+      end
+    end
+  end
 end
diff --git a/app/helpers/explore_helper.rb b/app/helpers/explore_helper.rb
index 7616fe6bad8b9ccda5b3f2406fe25b6817a86c8b..0d291f9a87e9551e06735ea42f0e4fd95be438a7 100644
--- a/app/helpers/explore_helper.rb
+++ b/app/helpers/explore_helper.rb
@@ -10,7 +10,7 @@ module ExploreHelper
 
     options = exist_opts.merge(options)
 
-    path = request.path
+    path = explore_projects_path
     path << "?#{options.to_param}"
     path
   end
diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb
index 77727337f07c6d6065d9cfe0f3ff65715a9e91d5..0e7d8065ac799003201fbf78cd125ba38c74b383 100644
--- a/app/helpers/tab_helper.rb
+++ b/app/helpers/tab_helper.rb
@@ -67,6 +67,14 @@ module TabHelper
       path.any? do |single_path|
         current_path?(single_path)
       end
+    elsif page = options.delete(:page)
+      unless page.respond_to?(:each)
+        page = [page]
+      end
+
+      page.any? do |single_page|
+        current_page?(single_page)
+      end
     else
       c = options.delete(:controller)
       a = options.delete(:action)
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 6d1ad82a262dfcc11394411099f18e6cb4859bbe..8f27e35d723c68e86dbc7220f79bde829214da8f 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -22,10 +22,12 @@
 #  user_oauth_applications      :boolean          default(TRUE)
 #  after_sign_out_path          :string(255)
 #  session_expire_delay         :integer          default(10080), not null
+#  import_sources               :text
 #
 
 class ApplicationSetting < ActiveRecord::Base
   serialize :restricted_visibility_levels
+  serialize :import_sources
   serialize :restricted_signup_domains, Array
   attr_accessor :restricted_signup_domains_raw
 
@@ -52,6 +54,16 @@ class ApplicationSetting < ActiveRecord::Base
     end
   end
 
+  validates_each :import_sources do |record, attr, value|
+    unless value.nil?
+      value.each do |source|
+        unless Gitlab::ImportSources.options.has_value?(source)
+          record.errors.add(attr, "'#{source}' is not a import source")
+        end
+      end
+    end
+  end
+
   def self.current
     ApplicationSetting.last
   end
@@ -70,7 +82,8 @@ class ApplicationSetting < ActiveRecord::Base
       session_expire_delay: Settings.gitlab['session_expire_delay'],
       default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'],
       default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'],
-      restricted_signup_domains: Settings.gitlab['restricted_signup_domains']
+      restricted_signup_domains: Settings.gitlab['restricted_signup_domains'],
+      import_sources: ['github','bitbucket','gitlab','gitorious','google_code','git']
     )
   end
 
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 324d1795ab4d90c56ea3c2452d7c451dd9c52aeb..467b90861f977ec0f075fcb01bff0faf1b201759 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -41,8 +41,6 @@ class MergeRequest < ActiveRecord::Base
 
   delegate :commits, :diffs, :last_commit, :last_commit_short_sha, to: :merge_request_diff, prefix: nil
 
-  attr_accessor :should_remove_source_branch
-
   # When this attribute is true some MR validation is ignored
   # It allows us to close or modify broken merge requests
   attr_accessor :allow_broken
@@ -57,7 +55,7 @@ class MergeRequest < ActiveRecord::Base
       transition [:reopened, :opened] => :closed
     end
 
-    event :merge do
+    event :mark_as_merged do
       transition [:reopened, :opened, :locked] => :merged
     end
 
@@ -205,7 +203,10 @@ class MergeRequest < ActiveRecord::Base
   end
 
   def check_if_can_be_merged
-    if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged?
+    can_be_merged =
+      project.repository.can_be_merged?(source_sha, target_branch)
+
+    if can_be_merged
       mark_as_mergeable
     else
       mark_as_unmergeable
@@ -220,18 +221,6 @@ class MergeRequest < ActiveRecord::Base
     self.target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::CLOSED).last
   end
 
-  def automerge!(current_user, commit_message = nil)
-    return unless automergeable?
-
-    MergeRequests::AutoMergeService.
-      new(target_project, current_user).
-      execute(self, commit_message)
-  end
-
-  def remove_source_branch?
-    self.should_remove_source_branch && !self.source_project.root_ref?(self.source_branch) && !self.for_fork?
-  end
-
   def open?
     opened? || reopened?
   end
@@ -240,11 +229,11 @@ class MergeRequest < ActiveRecord::Base
     title =~ /\A\[?WIP\]?:? /i
   end
 
-  def automergeable?
+  def mergeable?
     open? && !work_in_progress? && can_be_merged?
   end
 
-  def automerge_status
+  def gitlab_merge_status
     if work_in_progress?
       "work_in_progress"
     else
@@ -271,14 +260,14 @@ class MergeRequest < ActiveRecord::Base
   #
   # see "git diff"
   def to_diff(current_user)
-    Gitlab::Satellite::MergeAction.new(current_user, self).diff_in_satellite
+    target_project.repository.diff_text(target_branch, source_sha)
   end
 
   # Returns the commit as a series of email patches.
   #
   # see "git format-patch"
   def to_patch(current_user)
-    Gitlab::Satellite::MergeAction.new(current_user, self).format_patch
+    target_project.repository.format_patch(target_branch, source_sha)
   end
 
   def hook_attrs
@@ -429,4 +418,30 @@ class MergeRequest < ActiveRecord::Base
       "Open"
     end
   end
+
+  def target_sha
+    @target_sha ||= target_project.
+      repository.commit(target_branch).sha
+  end
+
+  def source_sha
+    commits.first.sha
+  end
+
+  def fetch_ref
+    target_project.repository.fetch_ref(
+      source_project.repository.path_to_repo,
+      "refs/heads/#{source_branch}",
+      "refs/merge-requests/#{iid}/head"
+    )
+  end
+
+  def in_locked_state
+    begin
+      lock_mr
+      yield
+    ensure
+      unlock_mr if locked?
+    end
+  end
 end
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index df1c2b78758225484d2e73c5615a386c784ee266..e317c8eac4d16bd1ddbd041acfebd7143ecd557a 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -16,9 +16,8 @@ require Rails.root.join("app/models/commit")
 class MergeRequestDiff < ActiveRecord::Base
   include Sortable
 
-  # Prevent store of diff
-  # if commits amount more then 200
-  COMMITS_SAFE_SIZE = 200
+  # Prevent store of diff if commits amount more then 500
+  COMMITS_SAFE_SIZE = 500
 
   attr_reader :commits, :diffs
 
@@ -124,12 +123,12 @@ class MergeRequestDiff < ActiveRecord::Base
     if new_diffs.any?
       if new_diffs.size > Commit::DIFF_HARD_LIMIT_FILES
         self.state = :overflow_diff_files_limit
-        new_diffs = []
+        new_diffs = new_diffs.first[Commit::DIFF_HARD_LIMIT_LINES]
       end
 
       if new_diffs.sum { |diff| diff.diff.lines.count } > Commit::DIFF_HARD_LIMIT_LINES
         self.state = :overflow_diff_lines_limit
-        new_diffs = []
+        new_diffs = new_diffs.first[Commit::DIFF_HARD_LIMIT_LINES]
       end
     end
 
@@ -160,12 +159,21 @@ class MergeRequestDiff < ActiveRecord::Base
   private
 
   def compare_result
-    @compare_result ||= CompareService.new.execute(
-      merge_request.author,
-      merge_request.source_project,
-      merge_request.source_branch,
-      merge_request.target_project,
-      merge_request.target_branch,
-    )
+    @compare_result ||=
+      begin
+        # Update ref for merge request
+        merge_request.fetch_ref
+
+        # Get latest sha of branch from source project
+        source_sha = merge_request.source_project.commit(source_branch).sha
+
+        Gitlab::CompareResult.new(
+          Gitlab::Git::Compare.new(
+            merge_request.target_project.repository.raw_repository,
+            merge_request.target_branch,
+            source_sha,
+          )
+        )
+      end
   end
 end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 30ffacaddeda00b0d37a71398f5d60773bc39894..161a16ca61c49fa83538291fc03f42ed838f63a0 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -118,12 +118,11 @@ class Namespace < ActiveRecord::Base
     gitlab_shell.add_namespace(path_was)
 
     if gitlab_shell.mv_namespace(path_was, path)
-      # If repositories moved successfully we need to remove old satellites
-      # and send update instructions to users.
+      # If repositories moved successfully we need to
+      # send update instructions to users.
       # However we cannot allow rollback since we moved namespace dir
       # So we basically we mute exceptions in next actions
       begin
-        gitlab_shell.rm_satellites(path_was)
         send_update_instructions
       rescue
         # Returning false does not rollback after_* transaction but gives
diff --git a/app/models/project.rb b/app/models/project.rb
index 3dc1729e812ebb48a0f83cdd142a7d72e43c502d..69f9af91c51d0b1c1fd4dea5dff7465e5f57a16c 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -215,7 +215,7 @@ class Project < ActiveRecord::Base
     end
 
     def search(query)
-      joins(:namespace).where('projects.archived = ?', false).
+      joins(:namespace).
         where('LOWER(projects.name) LIKE :query OR
               LOWER(projects.path) LIKE :query OR
               LOWER(namespaces.name) LIKE :query OR
@@ -520,14 +520,6 @@ class Project < ActiveRecord::Base
     !repository.exists? || repository.empty?
   end
 
-  def ensure_satellite_exists
-    self.satellite.create unless self.satellite.exists?
-  end
-
-  def satellite
-    @satellite ||= Gitlab::Satellite::Satellite.new(self)
-  end
-
   def repo
     repository.raw
   end
@@ -597,14 +589,11 @@ class Project < ActiveRecord::Base
     new_path_with_namespace = File.join(namespace_dir, path)
 
     if gitlab_shell.mv_repository(old_path_with_namespace, new_path_with_namespace)
-      # If repository moved successfully we need to remove old satellite
-      # and send update instructions to users.
+      # If repository moved successfully we need to send update instructions to users.
       # However we cannot allow rollback since we moved repository
       # So we basically we mute exceptions in next actions
       begin
         gitlab_shell.mv_repository("#{old_path_with_namespace}.wiki", "#{new_path_with_namespace}.wiki")
-        gitlab_shell.rm_satellites(old_path_with_namespace)
-        ensure_satellite_exists
         send_move_instructions
         reset_events_cache
       rescue
@@ -702,7 +691,6 @@ class Project < ActiveRecord::Base
   def create_repository
     if forked?
       if gitlab_shell.fork_repository(forked_from_project.path_with_namespace, self.namespace.path)
-        ensure_satellite_exists
         true
       else
         errors.add(:base, 'Failed to fork repository via gitlab-shell')
diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb
index 5aaa4e85cbcce8c2849b061eeb7b953dac0f8051..ecdcd48ae602476d8670fae8352fc7ed14cd718c 100644
--- a/app/models/project_services/gitlab_ci_service.rb
+++ b/app/models/project_services/gitlab_ci_service.rb
@@ -74,6 +74,8 @@ class GitlabCiService < CiService
     else
       :error
     end
+  rescue Errno::ECONNREFUSED
+    :error
   end
 
   def fork_registration(new_project, private_token)
@@ -103,6 +105,8 @@ class GitlabCiService < CiService
     if response.code == 200 and response["coverage"]
       response["coverage"]
     end
+  rescue Errno::ECONNREFUSED
+    nil
   end
 
   def build_page(sha, ref)
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 24c32d90051484cedc3a28cd647b73d257525fcf..79b48ebfedfe6bb833ed85005c6ae84c06646072 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -1,4 +1,9 @@
+require 'securerandom'
+
 class Repository
+  class PreReceiveError < StandardError; end
+  class CommitError < StandardError; end
+
   include Gitlab::ShellAdapter
 
   attr_accessor :raw_repository, :path_with_namespace, :project
@@ -368,6 +373,89 @@ class Repository
     @root_ref ||= raw_repository.root_ref
   end
 
+  def commit_file(user, path, content, message, branch)
+    commit_with_hooks(user, branch) do |ref|
+      path[0] = '' if path[0] == '/'
+
+      committer = user_to_comitter(user)
+      options = {}
+      options[:committer] = committer
+      options[:author] = committer
+      options[:commit] = {
+        message: message,
+        branch: ref,
+      }
+
+      options[:file] = {
+        content: content,
+        path: path
+      }
+
+      Gitlab::Git::Blob.commit(raw_repository, options)
+    end
+  end
+
+  def remove_file(user, path, message, branch)
+    commit_with_hooks(user, branch) do |ref|
+      path[0] = '' if path[0] == '/'
+
+      committer = user_to_comitter(user)
+      options = {}
+      options[:committer] = committer
+      options[:author] = committer
+      options[:commit] = {
+        message: message,
+        branch: ref
+      }
+
+      options[:file] = {
+        path: path
+      }
+
+      Gitlab::Git::Blob.remove(raw_repository, options)
+    end
+  end
+
+  def user_to_comitter(user)
+    {
+      email: user.email,
+      name: user.name,
+      time: Time.now
+    }
+  end
+
+  def can_be_merged?(source_sha, target_branch)
+    our_commit = rugged.branches[target_branch].target
+    their_commit = rugged.lookup(source_sha)
+
+    if our_commit && their_commit
+      !rugged.merge_commits(our_commit, their_commit).conflicts?
+    else
+      false
+    end
+  end
+
+  def merge(user, source_sha, target_branch, options = {})
+    our_commit = rugged.branches[target_branch].target
+    their_commit = rugged.lookup(source_sha)
+
+    raise "Invalid merge target" if our_commit.nil?
+    raise "Invalid merge source" if their_commit.nil?
+
+    merge_index = rugged.merge_commits(our_commit, their_commit)
+    return false if merge_index.conflicts?
+
+    commit_with_hooks(user, target_branch) do |ref|
+      actual_options = options.merge(
+        parents: [our_commit, their_commit],
+        tree: merge_index.write_tree(rugged),
+        update_ref: ref
+      )
+
+      Rugged::Commit.create(rugged, actual_options)
+    end
+  end
+
   def merged_to_root_ref?(branch_name)
     branch_commit = commit(branch_name)
     root_ref_commit = commit(root_ref)
@@ -412,6 +500,64 @@ class Repository
     )
   end
 
+  def fetch_ref(source_path, source_ref, target_ref)
+    args = %W(git fetch #{source_path} #{source_ref}:#{target_ref})
+    Gitlab::Popen.popen(args, path_to_repo)
+  end
+
+  def commit_with_hooks(current_user, branch)
+    oldrev = Gitlab::Git::BLANK_SHA
+    ref = Gitlab::Git::BRANCH_REF_PREFIX + branch
+    gl_id = Gitlab::ShellEnv.gl_id(current_user)
+    was_empty = empty?
+
+    # Create temporary ref
+    random_string = SecureRandom.hex
+    tmp_ref = "refs/tmp/#{random_string}/head"
+
+    unless was_empty
+      oldrev = find_branch(branch).target
+      rugged.references.create(tmp_ref, oldrev)
+    end
+
+    # Make commit in tmp ref
+    newrev = yield(tmp_ref)
+
+    unless newrev
+      raise CommitError.new('Failed to create commit')
+    end
+
+    # Run GitLab pre-receive hook
+    pre_receive_hook = Gitlab::Git::Hook.new('pre-receive', path_to_repo)
+    status = pre_receive_hook.trigger(gl_id, oldrev, newrev, ref)
+
+    if status
+      if was_empty
+        # Create branch
+        rugged.references.create(ref, newrev)
+      else
+        # Update head
+        current_head = find_branch(branch).target
+
+        # Make sure target branch was not changed during pre-receive hook
+        if current_head == oldrev
+          rugged.references.update(ref, newrev)
+        else
+          raise CommitError.new('Commit was rejected because branch received new push')
+        end
+      end
+
+      # Run GitLab post receive hook
+      post_receive_hook = Gitlab::Git::Hook.new('post-receive', path_to_repo)
+      status = post_receive_hook.trigger(gl_id, oldrev, newrev, ref)
+    else
+      # Remove tmp ref and return error to user
+      rugged.references.delete(tmp_ref)
+
+      raise PreReceiveError.new('Commit was rejected by pre-receive hook')
+    end
+  end
+
   private
 
   def cache
diff --git a/app/services/base_service.rb b/app/services/base_service.rb
index 6d9ed345914b356688422ad6dfbd72bf44d138b0..f00ec7408b683fb6f00e6c85c38ad04364bfeef3 100644
--- a/app/services/base_service.rb
+++ b/app/services/base_service.rb
@@ -31,6 +31,10 @@ class BaseService
     SystemHooksService.new
   end
 
+  def repository
+    project.repository
+  end
+
   # Add an error to the specified model for restricted visibility levels
   def deny_visibility_level(model, denied_visibility_level = nil)
     denied_visibility_level ||= model.visibility_level
diff --git a/app/services/compare_service.rb b/app/services/compare_service.rb
index 6aa9df4b19444aa24bff360649e71aafa9cc8986..70f642baaaaeca715782c6ca00b967b8c51c66ca 100644
--- a/app/services/compare_service.rb
+++ b/app/services/compare_service.rb
@@ -1,27 +1,28 @@
+require 'securerandom'
+
 # Compare 2 branches for one repo or between repositories
 # and return Gitlab::CompareResult object that responds to commits and diffs
 class CompareService
-  def execute(current_user, source_project, source_branch, target_project, target_branch)
-    # Try to compare branches to get commits list and diffs
-    #
-    # Note: Use satellite only when need to compare between two repos
-    # because satellites are slower than operations on bare repo
-    if target_project == source_project
-      Gitlab::CompareResult.new(
-        Gitlab::Git::Compare.new(
-          target_project.repository.raw_repository,
-          target_branch,
-          source_branch,
-        )
+  def execute(source_project, source_branch, target_project, target_branch)
+    source_sha = source_project.commit(source_branch).sha
+
+    # If compare with other project we need to fetch ref first
+    unless target_project == source_project
+      random_string = SecureRandom.hex
+
+      target_project.repository.fetch_ref(
+        source_project.repository.path_to_repo,
+        "refs/heads/#{source_branch}",
+        "refs/tmp/#{random_string}/head"
       )
-    else
-      Gitlab::Satellite::CompareAction.new(
-        current_user,
-        target_project,
-        target_branch,
-        source_project,
-        source_branch
-      ).result
     end
+
+    Gitlab::CompareResult.new(
+      Gitlab::Git::Compare.new(
+        target_project.repository.raw_repository,
+        target_branch,
+        source_sha,
+      )
+    )
   end
 end
diff --git a/app/services/files/base_service.rb b/app/services/files/base_service.rb
index bd245100955887034435ac0fe1c0a0584eaec9a9..7aecee217d856f12c967a6826e42bf063a250cd5 100644
--- a/app/services/files/base_service.rb
+++ b/app/services/files/base_service.rb
@@ -1,17 +1,75 @@
 module Files
   class BaseService < ::BaseService
-    attr_reader :ref, :path
+    class ValidationError < StandardError; end
 
-    def initialize(project, user, params, ref, path = nil)
-      @project, @current_user, @params = project, user, params.dup
-      @ref = ref
-      @path = path
+    def execute
+      @current_branch = params[:current_branch]
+      @target_branch  = params[:target_branch]
+      @commit_message = params[:commit_message]
+      @file_path      = params[:file_path]
+      @file_content   = if params[:file_content_encoding] == 'base64'
+                          Base64.decode64(params[:file_content])
+                        else
+                          params[:file_content]
+                        end
+
+      # Validate parameters
+      validate
+
+      # Create new branch if it different from current_branch
+      if @target_branch != @current_branch
+        create_target_branch
+      end
+
+      if sha = commit
+        success
+      else
+        error("Something went wrong. Your changes were not committed")
+      end
+    rescue Repository::CommitError, Repository::PreReceiveError, ValidationError => ex
+      error(ex.message)
     end
 
     private
 
-    def repository
-      project.repository
+    def current_branch
+      @current_branch ||= params[:current_branch]
+    end
+
+    def target_branch
+      @target_branch ||= params[:target_branch]
+    end
+
+    def raise_error(message)
+      raise ValidationError.new(message)
+    end
+
+    def validate
+      allowed = ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(@target_branch)
+
+      unless allowed
+        raise_error("You are not allowed to push into this branch")
+      end
+
+      unless project.empty_repo?
+        unless repository.branch_names.include?(@current_branch)
+          raise_error("You can only create files if you are on top of a branch")
+        end
+
+        if @current_branch != @target_branch
+          if repository.branch_names.include?(@target_branch)
+            raise_error("Branch with such name already exists. You need to switch to this branch in order to make changes")
+          end
+        end
+      end
+    end
+
+    def create_target_branch
+      result = CreateBranchService.new(project, current_user).execute(@target_branch, @current_branch)
+
+      unless result[:status] == :success
+        raise_error("Something went wrong when we tried to create #{@target_branch} for you")
+      end
     end
   end
 end
diff --git a/app/services/files/create_service.rb b/app/services/files/create_service.rb
index 23833aa78ec81e14cea22f95933f5064f1aabd32..91d715b2d637376ec18e268ee9aa3d4a1c46a340 100644
--- a/app/services/files/create_service.rb
+++ b/app/services/files/create_service.rb
@@ -1,52 +1,30 @@
 require_relative "base_service"
 
 module Files
-  class CreateService < BaseService
-    def execute
-      allowed = Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(ref)
+  class CreateService < Files::BaseService
+    def commit
+      repository.commit_file(current_user, @file_path, @file_content, @commit_message, @target_branch)
+    end
 
-      unless allowed
-        return error("You are not allowed to create file in this branch")
-      end
+    def validate
+      super
 
-      file_name = File.basename(path)
-      file_path = path
+      file_name = File.basename(@file_path)
 
       unless file_name =~ Gitlab::Regex.file_name_regex
-        return error(
+        raise_error(
           'Your changes could not be committed, because the file name ' +
           Gitlab::Regex.file_name_regex_message
         )
       end
 
-      if project.empty_repo?
-        # everything is ok because repo does not have a commits yet
-      else
-        unless repository.branch_names.include?(ref)
-          return error("You can only create files if you are on top of a branch")
-        end
-
-        blob = repository.blob_at_branch(ref, file_path)
+      unless project.empty_repo?
+        blob = repository.blob_at_branch(@current_branch, @file_path)
 
         if blob
-          return error("Your changes could not be committed, because file with such name exists")
+          raise_error("Your changes could not be committed, because file with such name exists")
         end
       end
-
-
-      new_file_action = Gitlab::Satellite::NewFileAction.new(current_user, project, ref, file_path)
-      created_successfully = new_file_action.commit!(
-        params[:content],
-        params[:commit_message],
-        params[:encoding],
-        params[:new_branch]
-      )
-
-      if created_successfully
-        success
-      else
-        error("Your changes could not be committed, because the file has been changed")
-      end
     end
   end
 end
diff --git a/app/services/files/delete_service.rb b/app/services/files/delete_service.rb
index 1497a0f883bcb32c5c85cdb3400a3960ea539de0..27c881c34308ad1bb360546bbfcee1bd49733d33 100644
--- a/app/services/files/delete_service.rb
+++ b/app/services/files/delete_service.rb
@@ -1,36 +1,9 @@
 require_relative "base_service"
 
 module Files
-  class DeleteService < BaseService
-    def execute
-      allowed = ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(ref)
-
-      unless allowed
-        return error("You are not allowed to push into this branch")
-      end
-
-      unless repository.branch_names.include?(ref)
-        return error("You can only create files if you are on top of a branch")
-      end
-
-      blob = repository.blob_at_branch(ref, path)
-
-      unless blob
-        return error("You can only edit text files")
-      end
-
-      delete_file_action = Gitlab::Satellite::DeleteFileAction.new(current_user, project, ref, path)
-
-      deleted_successfully = delete_file_action.commit!(
-        nil,
-        params[:commit_message]
-      )
-
-      if deleted_successfully
-        success
-      else
-        error("Your changes could not be committed, because the file has been changed")
-      end
+  class DeleteService < Files::BaseService
+    def commit
+      repository.remove_file(current_user, @file_path, @commit_message, @target_branch)
     end
   end
 end
diff --git a/app/services/files/update_service.rb b/app/services/files/update_service.rb
index 0724d3ae6347b1150c0c40f81cb36fbdb7c9dea8..a20903c6f02c13e8f4e014a56ce307fe1d829c3d 100644
--- a/app/services/files/update_service.rb
+++ b/app/services/files/update_service.rb
@@ -1,39 +1,9 @@
 require_relative "base_service"
 
 module Files
-  class UpdateService < BaseService
-    def execute
-      allowed = ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(ref)
-
-      unless allowed
-        return error("You are not allowed to push into this branch")
-      end
-
-      unless repository.branch_names.include?(ref)
-        return error("You can only create files if you are on top of a branch")
-      end
-
-      blob = repository.blob_at_branch(ref, path)
-
-      unless blob
-        return error("You can only edit text files")
-      end
-
-      edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, project, ref, path)
-      edit_file_action.commit!(
-        params[:content],
-        params[:commit_message],
-        params[:encoding],
-        params[:new_branch]
-      )
-
-      success
-    rescue Gitlab::Satellite::CheckoutFailed => ex
-      error("Your changes could not be committed because ref '#{ref}' could not be checked out", 400)
-    rescue Gitlab::Satellite::CommitFailed => ex
-      error("Your changes could not be committed. Maybe there was nothing to commit?", 409)
-    rescue Gitlab::Satellite::PushFailed => ex
-      error("Your changes could not be committed. Maybe the file was changed by another process?", 409)
+  class UpdateService < Files::BaseService
+    def commit
+      repository.commit_file(current_user, @file_path, @file_content, @commit_message, @target_branch)
     end
   end
 end
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index 5a2c97b08af95048a843f908189c1231ae6a7deb..81535450ac15f6cc0974f3d6452b7b74c3034197 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -10,16 +10,14 @@ class GitPushService
   #
   # Next, this method:
   #  1. Creates the push event
-  #  2. Ensures that the project satellite exists
-  #  3. Updates merge requests
-  #  4. Recognizes cross-references from commit messages
-  #  5. Executes the project's web hooks
-  #  6. Executes the project's services
+  #  2. Updates merge requests
+  #  3. Recognizes cross-references from commit messages
+  #  4. Executes the project's web hooks
+  #  5. Executes the project's services
   #
   def execute(project, user, oldrev, newrev, ref)
     @project, @user = project, user
 
-    project.ensure_satellite_exists
     project.repository.expire_cache
 
     if push_remove_branch?(ref, newrev)
@@ -133,7 +131,8 @@ class GitPushService
   end
 
   def is_default_branch?(ref)
-    Gitlab::Git.branch_ref?(ref) && Gitlab::Git.ref_name(ref) == project.default_branch
+    Gitlab::Git.branch_ref?(ref) &&
+      (Gitlab::Git.ref_name(ref) == project.default_branch || project.default_branch.nil?)
   end
 
   def commit_user(commit)
diff --git a/app/services/merge_requests/auto_merge_service.rb b/app/services/merge_requests/auto_merge_service.rb
deleted file mode 100644
index cdedf48b0c006f39c164d968ceb4130fa35efc66..0000000000000000000000000000000000000000
--- a/app/services/merge_requests/auto_merge_service.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-module MergeRequests
-  # AutoMergeService class
-  #
-  # Do git merge in satellite and in case of success
-  # mark merge request as merged and execute all hooks and notifications
-  # Called when you do merge via GitLab UI
-  class AutoMergeService < BaseMergeService
-    def execute(merge_request, commit_message)
-      merge_request.lock_mr
-
-      if Gitlab::Satellite::MergeAction.new(current_user, merge_request).merge!(commit_message)
-        merge_request.merge
-
-        create_merge_event(merge_request, current_user)
-        create_note(merge_request)
-        notification_service.merge_mr(merge_request, current_user)
-        execute_hooks(merge_request, 'merge')
-
-        true
-      else
-        merge_request.unlock_mr
-        false
-      end
-    rescue
-      merge_request.unlock_mr if merge_request.locked?
-      merge_request.mark_as_unmergeable
-      false
-    end
-  end
-end
diff --git a/app/services/merge_requests/base_merge_service.rb b/app/services/merge_requests/base_merge_service.rb
deleted file mode 100644
index 9579573adf9fb9ff34c1b59f08668b46b11b04b2..0000000000000000000000000000000000000000
--- a/app/services/merge_requests/base_merge_service.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-module MergeRequests
-  class BaseMergeService < MergeRequests::BaseService
-
-    private
-
-    def create_merge_event(merge_request, current_user)
-      EventCreateService.new.merge_mr(merge_request, current_user)
-    end
-  end
-end
diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb
index 956480938c398d27fb08b21d001000fe0467a855..a9b29f9654d716553330b62c48860e4da4d7d1bd 100644
--- a/app/services/merge_requests/build_service.rb
+++ b/app/services/merge_requests/build_service.rb
@@ -12,12 +12,16 @@ module MergeRequests
       merge_request.target_project ||= (project.forked_from_project || project)
       merge_request.target_branch ||= merge_request.target_project.default_branch
 
-      unless merge_request.target_branch && merge_request.source_branch
-        return build_failed(merge_request, nil)
+      if merge_request.target_branch.blank? || merge_request.source_branch.blank?
+        message =
+          if params[:source_branch] || params[:target_branch]
+            "You must select source and target branch"
+          end
+
+        return build_failed(merge_request, message)
       end
 
       compare_result = CompareService.new.execute(
-        current_user,
         merge_request.source_project,
         merge_request.source_branch,
         merge_request.target_project,
@@ -40,7 +44,6 @@ module MergeRequests
           merge_request.compare_diffs = diffs
 
         elsif diffs == false
-          # satellite timeout return false
           merge_request.can_be_created = false
           merge_request.compare_failed = true
         end
@@ -59,9 +62,6 @@ module MergeRequests
       end
 
       merge_request
-
-    rescue Gitlab::Satellite::BranchesWithoutParent
-      return build_failed(merge_request, "Selected branches have no common commit so they cannot be merged.")
     end
 
     def build_failed(merge_request, message)
diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb
index 327ead4ff3fe1fdb869aa415a48ee54ab9a222a5..98a67c0bc9937a197cf1f92d41e67219c5e6f025 100644
--- a/app/services/merge_requests/merge_service.rb
+++ b/app/services/merge_requests/merge_service.rb
@@ -1,22 +1,47 @@
 module MergeRequests
   # MergeService class
   #
-  # Mark existing merge request as merged
-  # and execute all hooks and notifications
-  # Called when you do merge via command line and push code
-  # to target branch
-  class MergeService < BaseMergeService
+  # Do git merge and in case of success
+  # mark merge request as merged and execute all hooks and notifications
+  # Executed when you do merge via GitLab UI
+  #
+  class MergeService < MergeRequests::BaseService
+    attr_reader :merge_request, :commit_message
+
     def execute(merge_request, commit_message)
-      merge_request.merge
+      @commit_message = commit_message
+      @merge_request = merge_request
+
+      unless @merge_request.mergeable?
+        return error('Merge request is not mergeable')
+      end
+
+      merge_request.in_locked_state do
+        if commit
+          after_merge
+          success
+        else
+          error('Can not merge changes')
+        end
+      end
+    end
 
-      create_merge_event(merge_request, current_user)
-      create_note(merge_request)
-      notification_service.merge_mr(merge_request, current_user)
-      execute_hooks(merge_request, 'merge')
+    private
+
+    def commit
+      committer = repository.user_to_comitter(current_user)
+
+      options = {
+        message: commit_message,
+        author: committer,
+        committer: committer
+      }
+
+      repository.merge(current_user, merge_request.source_sha, merge_request.target_branch, options)
+    end
 
-      true
-    rescue
-      false
+    def after_merge
+      MergeRequests::PostMergeService.new(project, current_user).execute(merge_request)
     end
   end
 end
diff --git a/app/services/merge_requests/post_merge_service.rb b/app/services/merge_requests/post_merge_service.rb
new file mode 100644
index 0000000000000000000000000000000000000000..aceb8cb902199cca00d3113fb2210800b2aa17e5
--- /dev/null
+++ b/app/services/merge_requests/post_merge_service.rb
@@ -0,0 +1,22 @@
+module MergeRequests
+  # PostMergeService class
+  #
+  # Mark existing merge request as merged
+  # and execute all hooks and notifications
+  #
+  class PostMergeService < MergeRequests::BaseService
+    def execute(merge_request)
+      merge_request.mark_as_merged
+      create_merge_event(merge_request, current_user)
+      create_note(merge_request)
+      notification_service.merge_mr(merge_request, current_user)
+      execute_hooks(merge_request, 'merge')
+    end
+
+    private
+
+    def create_merge_event(merge_request, current_user)
+      EventCreateService.new.merge_mr(merge_request, current_user)
+    end
+  end
+end
diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb
index d0648da049b42a2e4882874e872950515a0bee63..e903e48e3cd26daeb577dc4e5ecb3986dd315515 100644
--- a/app/services/merge_requests/refresh_service.rb
+++ b/app/services/merge_requests/refresh_service.rb
@@ -33,9 +33,9 @@ module MergeRequests
 
 
       merge_requests.uniq.select(&:source_project).each do |merge_request|
-        MergeRequests::MergeService.
+        MergeRequests::PostMergeService.
           new(merge_request.target_project, @current_user).
-          execute(merge_request, nil)
+          execute(merge_request)
       end
     end
 
diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb
index 403f419ec508b0043c1086779064d5737649077f..28872c89259d4f939d31d071cdab00f5f161e71b 100644
--- a/app/services/projects/destroy_service.rb
+++ b/app/services/projects/destroy_service.rb
@@ -27,7 +27,6 @@ module Projects
         end
       end
 
-      project.satellite.destroy
       log_info("Project \"#{project.name}\" was removed")
       system_hook_service.execute_hooks_for(project, :destroy)
       true
diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb
index f43c0ef70e9183e06275b35fab6f5cfc5082dfbc..550ed6897dd4c7afb857a747aae1b28b2f12def5 100644
--- a/app/services/projects/transfer_service.rb
+++ b/app/services/projects/transfer_service.rb
@@ -33,9 +33,6 @@ module Projects
           raise TransferError.new("Project with same path in target namespace already exists")
         end
 
-        # Remove old satellite
-        project.satellite.destroy
-
         # Apply new namespace id
         project.namespace = new_namespace
         project.save!
@@ -51,9 +48,6 @@ module Projects
         # Move wiki repo also if present
         gitlab_shell.mv_repository("#{old_path}.wiki", "#{new_path}.wiki")
 
-        # Create a new satellite (reload project from DB)
-        Project.find(project.id).ensure_satellite_exists
-
         # clear project cached events
         project.reset_events_cache
 
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index b67d2116fa4fa4cd9413aed447a9cb2ae462efe4..330b8bbf9d2c42905d9bf84995669de41eb946a6 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -27,6 +27,20 @@
           - restricted_level_checkboxes('restricted-visibility-help').each do |level|
             = level
         %span.help-block#restricted-visibility-help Selected levels cannot be used by non-admin users for projects or snippets
+    .form-group
+      = f.label :import_sources, class: 'control-label col-sm-2'
+      .col-sm-10
+        - data_attrs = { toggle: 'buttons' }
+        .btn-group{ data: data_attrs }
+          - import_sources_checkboxes('import-sources-help').each do |source|
+            = source
+        %span.help-block#import-sources-help
+          Enabled sources for code import during project creation. OmniAuth must be configured for GitHub
+          = link_to "(?)", help_page_path("integration", "github")
+          , Bitbucket
+          = link_to "(?)", help_page_path("integration", "bitbucket")
+          and GitLab.com
+          = link_to "(?)", help_page_path("integration", "gitlab")
     .form-group
       .col-sm-offset-2.col-sm-10
         .checkbox
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index f43d46356fa4c85524499343bed5b5e10f8e095a..d9b481404f75d1f9ae841d9a4341b72df08e255b 100644
--- a/app/views/admin/projects/index.html.haml
+++ b/app/views/admin/projects/index.html.haml
@@ -23,6 +23,10 @@
             = label_tag :abandoned do
               = check_box_tag :abandoned, 1, params[:abandoned]
               %span No activity over 6 month
+          .checkbox
+            = label_tag :with_archived do
+              = check_box_tag :with_archived, 1, params[:with_archived]
+              %span Show archived projects
 
         %fieldset
           %strong Visibility level:
@@ -73,6 +77,8 @@
                 = visibility_level_icon(project.visibility_level)
               = link_to project.name_with_namespace, [:admin, project.namespace.becomes(Namespace), project]
             .pull-right
+              - if project.archived
+                %span.label.label-warning archived
               %span.label.label-gray
                 = repository_size(project)
               = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm"
diff --git a/app/views/dashboard/_groups_head.html.haml b/app/views/dashboard/_groups_head.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..8a397a84e0ee1df98da2abad8098f926e1807ed8
--- /dev/null
+++ b/app/views/dashboard/_groups_head.html.haml
@@ -0,0 +1,7 @@
+%ul.center-top-menu
+  = nav_link(page: [dashboard_groups_path]) do
+    = link_to dashboard_groups_path, title: 'Your groups', data: {placement: 'right'} do
+      Your Groups
+  = nav_link(page: [explore_groups_path]) do
+    = link_to explore_groups_path, title: 'Explore groups', data: {toggle: 'tooltip', placement: 'bottom'} do
+      Explore Groups
diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..f7be194c696e61eab6c9714875eace2653950e48
--- /dev/null
+++ b/app/views/dashboard/_projects_head.html.haml
@@ -0,0 +1,10 @@
+%ul.center-top-menu
+  = nav_link(path: ['dashboard#show', 'root#show']) do
+    = link_to dashboard_path, title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do
+      Your Projects
+  = nav_link(page: starred_dashboard_projects_path) do
+    = link_to starred_dashboard_projects_path, title: 'Starred Projects', data: {placement: 'right'} do
+      Starred Projects
+  = nav_link(page: [explore_root_path, trending_explore_projects_path, starred_explore_projects_path, explore_projects_path]) do
+    = link_to explore_root_path, title: 'Explore', data: {toggle: 'tooltip', placement: 'bottom'} do
+      Explore Projects
diff --git a/app/views/dashboard/groups/index.html.haml b/app/views/dashboard/groups/index.html.haml
index 0a354373b9b07b59957f7eb15beae353012925c4..0860fe3c761e577c53f5fa4c2b8870d680f14793 100644
--- a/app/views/dashboard/groups/index.html.haml
+++ b/app/views/dashboard/groups/index.html.haml
@@ -1,14 +1,13 @@
 - page_title "Groups"
-%h3.page-title
-  Group Membership
+= render 'dashboard/groups_head'
+
+.slead
+  Group members have access to all group projects.
   - if current_user.can_create_group?
     %span.pull-right.hidden-xs
-      = link_to new_group_path, class: "btn btn-new" do
+      = link_to new_group_path, class: "btn btn-new btn-sm" do
         %i.fa.fa-plus
         New Group
-%p.light
-  Group members have access to all group projects.
-%hr
 .panel.panel-default
   .panel-heading
     %strong Groups
diff --git a/app/views/dashboard/projects/starred.html.haml b/app/views/dashboard/projects/starred.html.haml
index 8aaa0a7f071582794bbe9fbcc2179b7bcedd8829..98b8cde47666d6e5479539099e2222269a2a6de2 100644
--- a/app/views/dashboard/projects/starred.html.haml
+++ b/app/views/dashboard/projects/starred.html.haml
@@ -1,4 +1,6 @@
 - page_title "Starred Projects"
+= render 'dashboard/projects_head'
+
 - if @projects.any?
   = render 'shared/show_aside'
 
diff --git a/app/views/dashboard/show.html.haml b/app/views/dashboard/show.html.haml
index 5001c2101e1f2fadbd39901c473026e9d6659ee0..a3a32b6932f5afb31b594253dca2b73f0f4b10ac 100644
--- a/app/views/dashboard/show.html.haml
+++ b/app/views/dashboard/show.html.haml
@@ -2,6 +2,8 @@
   - if current_user
     = auto_discovery_link_tag(:atom, dashboard_url(format: :atom, private_token: current_user.private_token), title: "All activity")
 
+= render 'dashboard/projects_head'
+
 - if @projects.any?
   = render 'shared/show_aside'
 
diff --git a/app/views/explore/groups/index.html.haml b/app/views/explore/groups/index.html.haml
index f3f0b7785399eaee6d0625f3308e59dcafa7d081..7dcefd330a14930befe7c74ad0c4993712b5f6e9 100644
--- a/app/views/explore/groups/index.html.haml
+++ b/app/views/explore/groups/index.html.haml
@@ -1,5 +1,7 @@
 - page_title "Groups"
-.clearfix
+- if current_user
+  = render 'dashboard/groups_head'
+.clearfix.append-bottom-10
   .pull-left
     = form_tag explore_groups_path, method: :get, class: 'form-inline form-tiny' do |f|
       = hidden_field_tag :sort, @sort
@@ -28,15 +30,12 @@
           = link_to explore_groups_path(sort: sort_value_oldest_updated) do
             = sort_title_oldest_updated
 
-%hr
-
 %ul.bordered-list
   - @groups.each do |group|
     %li
       .clearfix
         %h4
           = link_to group_path(id: group.path) do
-            %i.fa.fa-users
             = group.name
       .clearfix
         %p
diff --git a/app/views/explore/projects/_dropdown.html.haml b/app/views/explore/projects/_dropdown.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..b23a3c1e5c170e5165627987c4ab6dfa5ae672d0
--- /dev/null
+++ b/app/views/explore/projects/_dropdown.html.haml
@@ -0,0 +1,27 @@
+.dropdown.inline
+  %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
+    %span.light sort:
+    - if @sort.present?
+      = sort_options_hash[@sort]
+    - elsif current_page?(trending_explore_projects_path) || current_page?(explore_root_path)
+      Trending projects
+    - elsif current_page?(starred_explore_projects_path)
+      Most stars
+    - else
+      = sort_title_recently_created
+    %b.caret
+  %ul.dropdown-menu
+    %li
+      = link_to trending_explore_projects_path do
+        Trending projects
+      = link_to starred_explore_projects_path do
+        Most stars
+      = link_to explore_projects_filter_path(sort: sort_value_recently_created) do
+        = sort_title_recently_created
+      = link_to explore_projects_filter_path(sort: sort_value_oldest_created) do
+        = sort_title_oldest_created
+      = link_to explore_projects_filter_path(sort: sort_value_recently_updated) do
+        = sort_title_recently_updated
+      = link_to explore_projects_filter_path(sort: sort_value_oldest_updated) do
+        = sort_title_oldest_updated
+
diff --git a/app/views/explore/projects/_filter.html.haml b/app/views/explore/projects/_filter.html.haml
index 82622a58ed2bb651e2b431370a1259d8bf83f70e..4b91291caf4879459c7c42f6e1bff63e42e75194 100644
--- a/app/views/explore/projects/_filter.html.haml
+++ b/app/views/explore/projects/_filter.html.haml
@@ -46,22 +46,4 @@
             = link_to explore_projects_filter_path(tag: tag.name) do
               %i.fa.fa-tag
               = tag.name
-
-  .dropdown.inline
-    %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
-      %span.light sort:
-      - if @sort.present?
-        = sort_options_hash[@sort]
-      - else
-        = sort_title_recently_created
-      %b.caret
-    %ul.dropdown-menu
-      %li
-        = link_to explore_projects_filter_path(sort: sort_value_recently_created) do
-          = sort_title_recently_created
-        = link_to explore_projects_filter_path(sort: sort_value_oldest_created) do
-          = sort_title_oldest_created
-        = link_to explore_projects_filter_path(sort: sort_value_recently_updated) do
-          = sort_title_recently_updated
-        = link_to explore_projects_filter_path(sort: sort_value_oldest_updated) do
-          = sort_title_oldest_updated
+  = render 'explore/projects/dropdown'
diff --git a/app/views/explore/projects/index.html.haml b/app/views/explore/projects/index.html.haml
index ba2276f51ce722da1353750696b49b36e28802b1..4956081e1ed5d17616d6c726ce75a8ab2d70b435 100644
--- a/app/views/explore/projects/index.html.haml
+++ b/app/views/explore/projects/index.html.haml
@@ -1,8 +1,9 @@
 - page_title "Projects"
+- if current_user
+  = render 'dashboard/projects_head'
 .clearfix
   = render 'filter'
-
-%hr
+%br
 .public-projects
   %ul.bordered-list.top-list
     = render @projects
diff --git a/app/views/explore/projects/starred.html.haml b/app/views/explore/projects/starred.html.haml
index b5d146b1f2fe296769b52f6b4a5576f3b56d91ce..fdccbe5692fd2dfec02e8ab26fe96ae5d0d86b13 100644
--- a/app/views/explore/projects/starred.html.haml
+++ b/app/views/explore/projects/starred.html.haml
@@ -1,9 +1,12 @@
 - page_title "Starred Projects"
+- if current_user
+  = render 'dashboard/projects_head'
 .explore-trending-block
-  %p.lead
+  .lead
     %i.fa.fa-star
     See most starred projects
-  %hr
+    .pull-right
+      = render 'explore/projects/dropdown'
   .public-projects
     %ul.bordered-list
       = render @starred_projects
diff --git a/app/views/explore/projects/trending.html.haml b/app/views/explore/projects/trending.html.haml
index 5e24df76a6370fd5c6e3ace9387697f6575f4d15..98a4174b426aaf5601ee4ba809ddb896f5b2a82c 100644
--- a/app/views/explore/projects/trending.html.haml
+++ b/app/views/explore/projects/trending.html.haml
@@ -1,4 +1,6 @@
 - page_title "Trending Projects"
+- if current_user
+  = render 'dashboard/projects_head'
 .explore-title
   %h3
     Explore GitLab
@@ -6,10 +8,11 @@
     Discover projects and groups. Share your projects with others
 %hr
 .explore-trending-block
-  %p.lead
+  .lead
     %i.fa.fa-comments-o
     See most discussed projects for last month
-  %hr
+    .pull-right
+      = render 'explore/projects/dropdown'
   .public-projects
     %ul.bordered-list
       = render @trending_projects
diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml
index 6b7efa83dead48eb166f9d4943060dd02d0b96fd..d06cfa7ff9fad3dd93c5e66b497266ad7ecb14a8 100644
--- a/app/views/groups/projects.html.haml
+++ b/app/views/groups/projects.html.haml
@@ -12,11 +12,14 @@
     - @projects.each do |project|
       %li
         .list-item-name
-          = visibility_level_icon(project.visibility_level)
+          %span{ class: visibility_level_color(project.visibility_level) }
+            = visibility_level_icon(project.visibility_level)
           %strong= link_to project.name_with_namespace, project
+        .pull-right
+          - if project.archived
+            %span.label.label-warning archived
           %span.label.label-gray
             = repository_size(project)
-        .pull-right
           = link_to 'Members', namespace_project_project_members_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm"
           = link_to 'Edit', edit_namespace_project_path(project.namespace, project), id: "edit_#{dom_id(project)}", class: "btn btn-sm"
           = link_to 'Remove', project, data: { confirm: remove_project_message(project)}, method: :delete, class: "btn btn-sm btn-remove"
diff --git a/app/views/layouts/explore.html.haml b/app/views/layouts/explore.html.haml
index 56bb92a536edbb41d2b4d2fc295a14d92d3f5d3b..17fee9c510db12af71c5cf6c51774150457f0c77 100644
--- a/app/views/layouts/explore.html.haml
+++ b/app/views/layouts/explore.html.haml
@@ -1,5 +1,8 @@
 - page_title    "Explore"
-- header_title  "Explore GitLab", explore_root_path
-- sidebar       "explore"
+- if current_user
+  - header_title  "Dashboard", root_path
+- else
+  - header_title  "Explore GitLab", explore_root_path
+- sidebar       "dashboard"
 
 = render template: "layouts/application"
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index b3cd7b0e37bfa8c8b95b6784dbf66a8d425b0f43..12ddbe6f1b72f90a24c7dba2c6f9d7039ae5959a 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -17,13 +17,13 @@
           %li.visible-sm.visible-xs
             = link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom'} do
               = icon('search')
-          %li.hidden-xs
+          -#%li.hidden-xs
             = link_to help_path, title: 'Help', data: {toggle: 'tooltip', placement: 'bottom'} do
               = icon('question-circle fw')
-          %li
+          -#%li
             = link_to explore_root_path, title: 'Explore', data: {toggle: 'tooltip', placement: 'bottom'} do
               = icon('globe fw')
-          %li
+          -#%li
             = link_to user_snippets_path(current_user), title: 'Your snippets', data: {toggle: 'tooltip', placement: 'bottom'} do
               = icon('clipboard fw')
           - if current_user.is_admin?
@@ -34,7 +34,7 @@
             %li.hidden-xs
               = link_to new_project_path, title: 'New project', data: {toggle: 'tooltip', placement: 'bottom'} do
                 = icon('plus fw')
-          %li
+          -#%li
             = link_to profile_path, title: 'Profile settings', data: {toggle: 'tooltip', placement: 'bottom'} do
               = icon('cog fw')
           %li
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
index 687c1fc3dd20bfe699927a214b378129e0f1b9f4..8f010196d1a2acdc03be0631a13484726b123857 100644
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -1,36 +1,43 @@
 %ul.nav.nav-sidebar
-  = nav_link(path: ['dashboard#show', 'root#show'], html_options: {class: 'home'}) do
-    = link_to dashboard_path, title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do
+  = nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do
+    = link_to (current_user ? root_path : explore_root_path), title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do
       = icon('dashboard fw')
       %span
-        Your Projects
-  = nav_link(path: 'projects#starred') do
-    = link_to starred_dashboard_projects_path, title: 'Starred Projects', data: {placement: 'right'} do
-      = icon('star fw')
-      %span
-        Starred Projects
+        Projects
   = nav_link(controller: :groups) do
-    = link_to dashboard_groups_path, title: 'Groups', data: {placement: 'right'} do
+    = link_to (current_user ? dashboard_groups_path : explore_groups_path), title: 'Groups', data: {placement: 'right'} do
       = icon('group fw')
       %span
         Groups
-  = nav_link(controller: :milestones) do
-    = link_to dashboard_milestones_path, title: 'Milestones', data: {placement: 'right'} do
-      = icon('clock-o fw')
-      %span
-        Milestones
-  = nav_link(path: 'dashboard#issues') do
-    = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'shortcuts-issues', data: {placement: 'right'} do
-      = icon('exclamation-circle fw')
-      %span
-        Issues
-        %span.count= current_user.assigned_issues.opened.count
-  = nav_link(path: 'dashboard#merge_requests') do
-    = link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'shortcuts-merge_requests', data: {placement: 'right'} do
-      = icon('tasks fw')
+  - if current_user
+    = nav_link(controller: :milestones) do
+      = link_to dashboard_milestones_path, title: 'Milestones', data: {placement: 'right'} do
+        = icon('clock-o fw')
+        %span
+          Milestones
+    = nav_link(path: 'dashboard#issues') do
+      = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'shortcuts-issues', data: {placement: 'right'} do
+        = icon('exclamation-circle fw')
+        %span
+          Issues
+          %span.count= current_user.assigned_issues.opened.count
+    = nav_link(path: 'dashboard#merge_requests') do
+      = link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'shortcuts-merge_requests', data: {placement: 'right'} do
+        = icon('tasks fw')
+        %span
+          Merge Requests
+          %span.count= current_user.assigned_merge_requests.opened.count
+  = nav_link(controller: :snippets) do
+    = link_to (current_user ? user_snippets_path(current_user) : snippets_path), title: 'Your snippets', data: {placement: 'right'} do
+      = icon('dashboard fw')
       %span
-        Merge Requests
-        %span.count= current_user.assigned_merge_requests.opened.count
+        Snippets
+  - if current_user
+    = nav_link(controller: :profile) do
+      = link_to profile_path, title: 'Profile settings', data: {toggle: 'tooltip', placement: 'bottom'} do
+        = icon('user fw')
+        %span
+          Profile
   = nav_link(controller: :help) do
     = link_to help_path, title: 'Help', data: {placement: 'right'} do
       = icon('question-circle fw')
diff --git a/app/views/layouts/nav/_explore.html.haml b/app/views/layouts/nav/_explore.html.haml
deleted file mode 100644
index 66870e84ceb1470f97b960e440542c60a8cd472c..0000000000000000000000000000000000000000
--- a/app/views/layouts/nav/_explore.html.haml
+++ /dev/null
@@ -1,18 +0,0 @@
-%ul.nav.nav-sidebar
-  = nav_link(path: 'projects#trending') do
-    = link_to explore_root_path, title: 'Trending Projects', data: {placement: 'right'} do
-      = icon('comments fw')
-      %span Trending Projects
-  = nav_link(path: 'projects#starred') do
-    = link_to starred_explore_projects_path, title: 'Most-starred Projects', data: {placement: 'right'} do
-      = icon('star fw')
-      %span Most-starred Projects
-  = nav_link(path: 'projects#index') do
-    = link_to explore_projects_path, title: 'All Projects', data: {placement: 'right'} do
-      = icon('bookmark fw')
-      %span All Projects
-  = nav_link(controller: :groups) do
-    = link_to explore_groups_path, title: 'All Groups', data: {placement: 'right'} do
-      = icon('group fw')
-      %span All Groups
-
diff --git a/app/views/layouts/nav/_snippets.html.haml b/app/views/layouts/nav/_snippets.html.haml
deleted file mode 100644
index 458b76a2c99808eb02cc42a8c4ad4ca2c3de35ab..0000000000000000000000000000000000000000
--- a/app/views/layouts/nav/_snippets.html.haml
+++ /dev/null
@@ -1,12 +0,0 @@
-%ul.nav.nav-sidebar
-  - if current_user
-    = nav_link(path: user_snippets_path(current_user), html_options: {class: 'home'}) do
-      = link_to user_snippets_path(current_user), title: 'Your snippets', data: {placement: 'right'} do
-        = icon('dashboard fw')
-        %span
-          Your Snippets
-  = nav_link(path: snippets_path) do
-    = link_to snippets_path, title: 'Discover snippets', data: {placement: 'right'} do
-      = icon('globe fw')
-      %span
-        Discover Snippets
diff --git a/app/views/layouts/snippets.html.haml b/app/views/layouts/snippets.html.haml
index 9b0f40073ab79061cc7da12c3ff391377ffc6fa0..b77fe09fc2a20f50c68083572c7c7964b894061e 100644
--- a/app/views/layouts/snippets.html.haml
+++ b/app/views/layouts/snippets.html.haml
@@ -1,5 +1,8 @@
 - page_title    'Snippets'
-- header_title  'Snippets', snippets_path
-- sidebar       "snippets"
+- if current_user
+  - header_title  "Dashboard", root_path
+- else
+  - header_title  'Snippets', snippets_path
+- sidebar       "dashboard"
 
 = render template: "layouts/application"
diff --git a/app/views/profiles/two_factor_auths/_codes.html.haml b/app/views/profiles/two_factor_auths/_codes.html.haml
index 1b1395eaa17b5105709af1aa81a7c788f3f64261..43b58be7f98cc5697d31cfa25db125a5fd41a5c4 100644
--- a/app/views/profiles/two_factor_auths/_codes.html.haml
+++ b/app/views/profiles/two_factor_auths/_codes.html.haml
@@ -1,6 +1,8 @@
 %p.slead
   Should you ever lose your phone, each of these recovery codes can be used one
-  time each to regain access to your account. Please save them in a safe place.
+  time each to regain access to your account. Please save them in a safe place, or you
+  %b will
+  lose access to your account.
 
 .codes.well
   %ul
diff --git a/app/views/projects/_bitbucket_import_modal.html.haml b/app/views/projects/_bitbucket_import_modal.html.haml
index 745163e79a79733f5052403dd824a9bd6ff23139..2987f6b5b226be7e572768187050408192ed8985 100644
--- a/app/views/projects/_bitbucket_import_modal.html.haml
+++ b/app/views/projects/_bitbucket_import_modal.html.haml
@@ -5,9 +5,9 @@
         %a.close{href: "#", "data-dismiss" => "modal"} ×
         %h3 Import projects from Bitbucket
       .modal-body
-        To enable importing projects from Bitbucket, 
+        To enable importing projects from Bitbucket,
         - if current_user.admin?
-          you need to
+          as administrator you need to configure
         - else
-          your GitLab administrator needs to
-        == #{link_to 'setup OAuth integration', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/bitbucket.md'}.
+          ask your GitLab administrator to configure
+        == #{link_to 'OAuth integration', help_page_path("integration", "bitbucket")}.
diff --git a/app/views/projects/_github_import_modal.html.haml b/app/views/projects/_github_import_modal.html.haml
index de58b27df238fe1c65293808835c41b280af4f30..46ad1559356ea26ece89af7db6548264e02a6721 100644
--- a/app/views/projects/_github_import_modal.html.haml
+++ b/app/views/projects/_github_import_modal.html.haml
@@ -5,9 +5,9 @@
         %a.close{href: "#", "data-dismiss" => "modal"} ×
         %h3 Import projects from GitHub
       .modal-body
-        To enable importing projects from GitHub, 
+        To enable importing projects from GitHub,
         - if current_user.admin?
-          you need to
+          as administrator you need to configure
         - else
-          your GitLab administrator needs to
-        == #{link_to 'setup OAuth integration', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/github.md'}.
\ No newline at end of file
+          ask your Gitlab administrator to configure
+        == #{link_to 'OAuth integration', help_page_path("integration", "github")}.
diff --git a/app/views/projects/_gitlab_import_modal.html.haml b/app/views/projects/_gitlab_import_modal.html.haml
index ae6c25f9371c148e7560dc99b60b0a253fd3fcad..377cf0187b880d03126a5e4b8f3e30f3e53776f5 100644
--- a/app/views/projects/_gitlab_import_modal.html.haml
+++ b/app/views/projects/_gitlab_import_modal.html.haml
@@ -5,9 +5,9 @@
         %a.close{href: "#", "data-dismiss" => "modal"} ×
         %h3 Import projects from GitLab.com
       .modal-body
-        To enable importing projects from GitLab.com, 
+        To enable importing projects from GitLab.com,
         - if current_user.admin?
-          you need to
+          as administrator you need to configure
         - else
-          your GitLab administrator needs to
-        == #{link_to 'setup OAuth integration', 'https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/integration/gitlab.md'}.
\ No newline at end of file
+          ask your GitLab administrator to configure
+        == #{link_to 'OAuth integration', help_page_path("integration", "gitlab")}.
diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml
index 96f188e4aa7ab644487318d53faf2a021a4053b7..9c3e1703c893148dc66df5cf6e31ccaa684104c8 100644
--- a/app/views/projects/blob/_editor.html.haml
+++ b/app/views/projects/blob/_editor.html.haml
@@ -12,8 +12,8 @@
         \/
         = text_field_tag 'file_name', params[:file_name], placeholder: "File name",
           required: true, class: 'form-control new-file-name'
-        .pull-right
-          = select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'form-control'
+      .pull-right
+        = select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'form-control'
 
   .file-content.code
     %pre.js-edit-mode-pane#editor
diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml
index dac984f8c3155e8ef1058a3a9f4c12d579bdcaed..7c2a4fece944aee7140a5304af4703fce8730ab6 100644
--- a/app/views/projects/blob/new.html.haml
+++ b/app/views/projects/blob/new.html.haml
@@ -6,11 +6,12 @@
     = render 'shared/commit_message_container', params: params,
              placeholder: 'Add new file'
 
-    .form-group.branch
-      = label_tag 'branch', class: 'control-label' do
-        Branch
-      .col-sm-10
-        = text_field_tag 'new_branch', @ref, class: "form-control"
+    - unless @project.empty_repo?
+      .form-group.branch
+        = label_tag 'branch', class: 'control-label' do
+          Branch
+        .col-sm-10
+          = text_field_tag 'new_branch', @ref, class: "form-control"
 
     = hidden_field_tag 'content', '', id: 'file-content'
     = render 'projects/commit_button', ref: @ref,
diff --git a/app/views/projects/merge_requests/_new_compare.html.haml b/app/views/projects/merge_requests/_new_compare.html.haml
index ff9c0cdb283c6953922e01c99a4fbe36c4cc674d..7709330611a835944fdf89c5e2213edfacfaa96e 100644
--- a/app/views/projects/merge_requests/_new_compare.html.haml
+++ b/app/views/projects/merge_requests/_new_compare.html.haml
@@ -35,7 +35,7 @@
     - if @merge_request.compare_failed
       .alert.alert-danger
         %h4 Compare failed
-        %p We can't compare selected branches. It may be because of huge diff or satellite timeout. Please try again or select different branches.
+        %p We can't compare selected branches. It may be because of huge diff. Please try again or select different branches.
     - else
       .light-well
         .center
diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml
index 633a54f3620cc132e8e932a40bc8b8d8cc7c3802..76f44211dac3f7fb821600003afb37f0ec892120 100644
--- a/app/views/projects/merge_requests/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/_new_submit.html.haml
@@ -24,7 +24,7 @@
         = icon('history')
         Commits
         %span.badge= @commits.size
-    %li.diffs-tab
+    %li.diffs-tab.active
       = link_to url_for(params), data: {target: '#diffs', action: 'diffs', toggle: 'tab'} do
         = icon('list-alt')
         Changes
@@ -33,7 +33,7 @@
   .tab-content
     #commits.commits.tab-pane
       = render "projects/commits/commits", project: @project
-    #diffs.diffs.tab-pane
+    #diffs.diffs.tab-pane.active
       - if @diffs.present?
         = render "projects/diffs/diffs", diffs: @diffs, project: @project
       - elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
diff --git a/app/views/projects/merge_requests/automerge.js.haml b/app/views/projects/merge_requests/merge.js.haml
similarity index 100%
rename from app/views/projects/merge_requests/automerge.js.haml
rename to app/views/projects/merge_requests/merge.js.haml
diff --git a/app/views/projects/merge_requests/show/_commits.html.haml b/app/views/projects/merge_requests/show/_commits.html.haml
index 3b7f283daf0468774e60114d0c3490d26c71cefc..a71b181a6a5c44af70df4293c44183f104a5ded8 100644
--- a/app/views/projects/merge_requests/show/_commits.html.haml
+++ b/app/views/projects/merge_requests/show/_commits.html.haml
@@ -1 +1 @@
-= render "projects/commits/commits", project: @merge_request.source_project
+= render "projects/commits/commits", project: @merge_request.project
diff --git a/app/views/projects/merge_requests/show/_diffs.html.haml b/app/views/projects/merge_requests/show/_diffs.html.haml
index 786b5f39063327cf28f8dca26d3f89965b46f7cd..626970f39be61a083b87ef44a7522bef57255e72 100644
--- a/app/views/projects/merge_requests/show/_diffs.html.haml
+++ b/app/views/projects/merge_requests/show/_diffs.html.haml
@@ -1,5 +1,5 @@
 - if @merge_request_diff.collected?
-  = render "projects/diffs/diffs", diffs: @merge_request.diffs, project: @merge_request.source_project
+  = render "projects/diffs/diffs", diffs: @merge_request.diffs, project: @merge_request.project
 - elsif @merge_request_diff.empty?
   .nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
 - else
diff --git a/app/views/projects/merge_requests/widget/_open.html.haml b/app/views/projects/merge_requests/widget/_open.html.haml
index 8c61e8193745c8956d4b631b837a61c51f6f8279..0aad9bb3e88e0507eb56af53618271f2e525c499 100644
--- a/app/views/projects/merge_requests/widget/_open.html.haml
+++ b/app/views/projects/merge_requests/widget/_open.html.haml
@@ -3,8 +3,6 @@
   .mr-widget-body
     - if @project.archived?
       = render 'projects/merge_requests/widget/open/archived'
-    - elsif !@project.satellite.exists?
-      = render 'projects/merge_requests/widget/open/no_satellite'
     - elsif @merge_request.commits.blank?
       = render 'projects/merge_requests/widget/open/nothing'
     - elsif @merge_request.branch_missing?
diff --git a/app/views/projects/merge_requests/widget/_show.html.haml b/app/views/projects/merge_requests/widget/_show.html.haml
index 263cab7a9e8866b45fde34d824d80bbbef0109a9..a489d4f9b24ee4e675a9ce4e3299408e0816c20f 100644
--- a/app/views/projects/merge_requests/widget/_show.html.haml
+++ b/app/views/projects/merge_requests/widget/_show.html.haml
@@ -11,10 +11,10 @@
   var merge_request_widget;
 
   merge_request_widget = new MergeRequestWidget({
-    url_to_automerge_check: "#{automerge_check_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
+    url_to_automerge_check: "#{merge_check_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
     check_enable: #{@merge_request.unchecked? ? "true" : "false"},
     url_to_ci_check: "#{ci_status_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
     ci_enable: #{@project.ci_service ? "true" : "false"},
-    current_status: "#{@merge_request.automerge_status}",
+    current_status: "#{@merge_request.gitlab_merge_status}",
   });
 
diff --git a/app/views/projects/merge_requests/widget/open/_accept.html.haml b/app/views/projects/merge_requests/widget/open/_accept.html.haml
index df20205de1cae6205686d19425f801c14fc092b2..b61e193fc429e1921b30da7486f7f168575f93c3 100644
--- a/app/views/projects/merge_requests/widget/open/_accept.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_accept.html.haml
@@ -1,4 +1,4 @@
-= form_for [:automerge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form js-requires-input' } do |f|
+= form_for [:merge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form js-requires-input' } do |f|
   = hidden_field_tag :authenticity_token, form_authenticity_token
   .accept-merge-holder.clearfix.js-toggle-container
     .accept-action
diff --git a/app/views/projects/merge_requests/widget/open/_no_satellite.html.haml b/app/views/projects/merge_requests/widget/open/_no_satellite.html.haml
deleted file mode 100644
index 3718cfd83339b4be6e5d6200f58696e46bce4acd..0000000000000000000000000000000000000000
--- a/app/views/projects/merge_requests/widget/open/_no_satellite.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-%p
-  %span
-    %strong This repository does not have a satellite. Please ask an administrator to fix this issue!
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index d25fe68242b5415b123091bd466da9d12c0ba103..636218368cc603229f3a658cb07ca9d527061b14 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -22,70 +22,75 @@
           .col-sm-10
             = f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user), {}, {class: 'select2', tabindex: 2}
 
-      %hr
+      - if import_sources_enabled?
+        %hr
 
-      .project-import.js-toggle-container
-        .form-group
-          %label.control-label Import project from
-          .col-sm-10
-            - if github_import_enabled?
-              = link_to status_import_github_path, class: 'btn' do
-                %i.fa.fa-github
-                GitHub
-            - else
-              = link_to '#', class: 'how_to_import_link light btn' do
-                %i.fa.fa-github
-                GitHub
-              = render 'github_import_modal'
-
-
-            - if bitbucket_import_enabled?
-              = link_to status_import_bitbucket_path, class: 'btn', "data-no-turbolink" => "true" do
-                %i.fa.fa-bitbucket
-                Bitbucket
-            - else
-              = link_to '#', class: 'how_to_import_link light btn' do
-                %i.fa.fa-bitbucket
-                Bitbucket
-              = render 'bitbucket_import_modal'
-
-            - unless request.host == 'gitlab.com'
-              - if gitlab_import_enabled?
-                = link_to status_import_gitlab_path, class: 'btn' do
-                  %i.fa.fa-heart
-                  GitLab.com
-              - else
-                = link_to '#', class: 'how_to_import_link light btn' do
-                  %i.fa.fa-heart
-                  GitLab.com
-                = render 'gitlab_import_modal'
-
-            = link_to new_import_gitorious_path, class: 'btn' do
-              %i.icon-gitorious.icon-gitorious-small
-              Gitorious.org
-
-            = link_to new_import_google_code_path, class: 'btn' do
-              %i.fa.fa-google
-              Google Code
-
-            = link_to "#", class: 'btn js-toggle-button' do
-              %i.fa.fa-git
-              %span Any repo by URL
-
-        .js-toggle-content.hide
-          .form-group.import-url-data
-            = f.label :import_url, class: 'control-label' do
-              %span Git repository URL
+        .project-import.js-toggle-container
+          .form-group
+            %label.control-label Import project from
             .col-sm-10
-              = f.text_field :import_url, class: 'form-control', placeholder: 'https://username:password@gitlab.company.com/group/project.git'
-              .well.prepend-top-20
-                %ul
-                  %li
-                    The repository must be accessible over HTTP(S). If it is not publicly accessible, you can add authentication information to the URL: <code>https://username:password@gitlab.company.com/group/project.git</code>.
-                  %li
-                    The import will time out after 4 minutes. For big repositories, use a clone/push combination.
-                  %li
-                    To migrate an SVN repository, check out #{link_to "this document", "http://doc.gitlab.com/ce/workflow/importing/migrating_from_svn.html"}.
+              - if github_import_enabled?
+                - if github_import_configured?
+                  = link_to status_import_github_path, class: 'btn import_github' do
+                    %i.fa.fa-github
+                    GitHub
+                - else
+                  = link_to '#', class: 'how_to_import_link light btn import_github' do
+                    %i.fa.fa-github
+                    GitHub
+                  = render 'github_import_modal'
+
+              - if bitbucket_import_enabled?
+                - if bitbucket_import_configured?
+                  = link_to status_import_bitbucket_path, class: 'btn import_bitbucket', "data-no-turbolink" => "true" do
+                    %i.fa.fa-bitbucket
+                    Bitbucket
+                - else
+                  = link_to status_import_bitbucket_path, class: 'how_to_import_link light btn import_bitbucket', "data-no-turbolink" => "true" do
+                    %i.fa.fa-bitbucket
+                    Bitbucket
+                  = render 'bitbucket_import_modal'
+
+              - if gitlab_import_enabled?
+                - if gitlab_import_configured?
+                  = link_to status_import_gitlab_path, class: 'btn import_gitlab' do
+                    %i.fa.fa-heart
+                    GitLab.com
+                - else
+                  = link_to status_import_gitlab_path, class: 'how_to_import_link light btn import_gitlab' do
+                    %i.fa.fa-heart
+                    GitLab.com
+                  = render 'gitlab_import_modal'
+
+              - if gitorious_import_enabled?
+                = link_to new_import_gitorious_path, class: 'btn import_gitorious' do
+                  %i.icon-gitorious.icon-gitorious-small
+                  Gitorious.org
+
+              - if google_code_import_enabled?
+                = link_to new_import_google_code_path, class: 'btn import_google_code' do
+                  %i.fa.fa-google
+                  Google Code
+
+              - if git_import_enabled?
+                = link_to "#", class: 'btn js-toggle-button import_git' do
+                  %i.fa.fa-git
+                  %span Any repo by URL
+
+          .js-toggle-content.hide
+            .form-group.import-url-data
+              = f.label :import_url, class: 'control-label' do
+                %span Git repository URL
+              .col-sm-10
+                = f.text_field :import_url, class: 'form-control', placeholder: 'https://username:password@gitlab.company.com/group/project.git'
+                .well.prepend-top-20
+                  %ul
+                    %li
+                      The repository must be accessible over HTTP(S). If it is not publicly accessible, you can add authentication information to the URL: <code>https://username:password@gitlab.company.com/group/project.git</code>.
+                    %li
+                      The import will time out after 4 minutes. For big repositories, use a clone/push combination.
+                    %li
+                      To migrate an SVN repository, check out #{link_to "this document", "http://doc.gitlab.com/ce/workflow/importing/migrating_from_svn.html"}.
 
       %hr.prepend-botton-10
 
diff --git a/app/views/snippets/_head.html.haml b/app/views/snippets/_head.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..0adf6b91f2c895c4d4600e4b0de6b6f29d098226
--- /dev/null
+++ b/app/views/snippets/_head.html.haml
@@ -0,0 +1,7 @@
+%ul.center-top-menu
+  = nav_link(page: user_snippets_path(current_user), html_options: {class: 'home'}) do
+    = link_to user_snippets_path(current_user), title: 'Your snippets', data: {placement: 'right'} do
+      Your Snippets
+  = nav_link(page: snippets_path) do
+    = link_to snippets_path, title: 'Explore snippets', data: {placement: 'right'} do
+      Explore Snippets
diff --git a/app/views/snippets/current_user_index.html.haml b/app/views/snippets/current_user_index.html.haml
index 0718f743828651fea87fe43f0b6ba40d526c4447..62a967a2e069d624b5a17ab1899b32fc56cb5fc3 100644
--- a/app/views/snippets/current_user_index.html.haml
+++ b/app/views/snippets/current_user_index.html.haml
@@ -1,13 +1,13 @@
 - page_title "Your Snippets"
-%h3.page-title
-  Your Snippets
-  .pull-right
-    = link_to new_snippet_path, class: "btn btn-new btn-grouped", title: "New Snippet" do
-      Add new snippet
+= render 'head'
 
-%p.light
+.slead
   Share code pastes with others out of git repository
 
+  .pull-right
+    = link_to new_snippet_path, class: "btn btn-new btn-sm", title: "New Snippet" do
+      Add new snippet
+
 %ul.nav.nav-tabs
   = nav_tab :scope, nil do
     = link_to user_snippets_path(@user) do
diff --git a/app/views/snippets/index.html.haml b/app/views/snippets/index.html.haml
index e9bb6a908d3db508c55534dc617c3743d7afde30..8608815e0a68d5a89dbd43c7e4a4bf0529f1d62e 100644
--- a/app/views/snippets/index.html.haml
+++ b/app/views/snippets/index.html.haml
@@ -1,17 +1,9 @@
 - page_title "Public Snippets"
-%h3.page-title
-  Public snippets
+- if current_user
+  = render 'head'
 
-  .pull-right
-    - if current_user
-      = link_to new_snippet_path, class: "btn btn-new btn-grouped", title: "New Snippet" do
-        Add new snippet
-      = link_to user_snippets_path(current_user), class: "btn btn-grouped"  do
-        Your snippets
-
-%p.light
+.slead
   Public snippets created by you and other users are listed here
 
-%hr
 = render 'snippets'
 
diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml
index 089e81229188688a0a5c0815c474b970a178a2a5..aed00f9caebfe3bd7c76bc47db375492fc5dbfb7 100644
--- a/app/views/snippets/show.html.haml
+++ b/app/views/snippets/show.html.haml
@@ -1,5 +1,5 @@
 - page_title @snippet.title, "Snippets"
-%h3.page-title
+%h4.page-title
   = @snippet.title
 
   - if @snippet.private?
@@ -8,17 +8,14 @@
       private
 
   .pull-right
-    = link_to new_snippet_path, class: "btn btn-new", title: "New Snippet" do
+    = link_to new_snippet_path, class: "btn btn-new btn-sm", title: "New Snippet" do
       Add new snippet
-%hr
 
-.append-bottom-20
+.append-bottom-10.prepend-top-10
   .pull-right
-    = "##{@snippet.id}"
     %span.light
-      by
+      created by
       = link_to user_snippets_path(@snippet.author) do
-        = image_tag avatar_icon(@snippet.author_email), class: "avatar avatar-inline s16", alt: ''
         = @snippet.author_name
 
   .back-link
@@ -27,7 +24,7 @@
         &larr; your snippets
     - else
       = link_to snippets_path do
-        &larr; discover snippets
+        &larr; explore snippets
 
 .file-holder
   .file-title
diff --git a/app/views/snippets/user_index.html.haml b/app/views/snippets/user_index.html.haml
index 23700eb39dafc6910859ddefac764f4734edd733..7af5352da34211d41c8781dea5ca2f3fe14dd748 100644
--- a/app/views/snippets/user_index.html.haml
+++ b/app/views/snippets/user_index.html.haml
@@ -1,14 +1,13 @@
 - page_title "Snippets", @user.name
-%h3.page-title
-  = image_tag avatar_icon(@user.email), class: "avatar s24"
-  = @user.name
-  %span
-    \/
-    Snippets
-  - if current_user
-    = link_to new_snippet_path, class: "btn btn-sm add_new pull-right", title: "New Snippet" do
-      Add new snippet
 
-%hr
+%ol.breadcrumb
+  %li
+    = link_to snippets_path do
+      Snippets
+  %li
+    = @user.name
+  .pull-right.hidden-xs
+    = link_to user_path(@user) do
+      #{@user.name} profile page
 
 = render 'snippets'
diff --git a/app/workers/auto_merge_worker.rb b/app/workers/auto_merge_worker.rb
deleted file mode 100644
index a6dd73eee5f81c8cff509d63b2294c0b05ae26a0..0000000000000000000000000000000000000000
--- a/app/workers/auto_merge_worker.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class AutoMergeWorker
-  include Sidekiq::Worker
-
-  sidekiq_options queue: :default
-
-  def perform(merge_request_id, current_user_id, params)
-    params = params.with_indifferent_access
-    current_user = User.find(current_user_id)
-    merge_request = MergeRequest.find(merge_request_id)
-    merge_request.should_remove_source_branch = params[:should_remove_source_branch]
-    merge_request.automerge!(current_user, params[:commit_message])
-  end
-end
diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6a8665c179ab89057561511623dae4949e890c75
--- /dev/null
+++ b/app/workers/merge_worker.rb
@@ -0,0 +1,19 @@
+class MergeWorker
+  include Sidekiq::Worker
+
+  sidekiq_options queue: :default
+
+  def perform(merge_request_id, current_user_id, params)
+    params = params.with_indifferent_access
+    current_user = User.find(current_user_id)
+    merge_request = MergeRequest.find(merge_request_id)
+
+    result = MergeRequests::MergeService.new(merge_request.target_project, current_user).
+      execute(merge_request, params[:commit_message])
+
+    if result[:status] == :success && params[:should_remove_source_branch].present?
+      DeleteBranchService.new(merge_request.source_project, current_user).
+        execute(merge_request.source_branch)
+    end
+  end
+end
diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb
index 94832872d13ddccb192eaf05ac1d29f269b1bd57..b546f8777e158405b5459338f0944ab2b677e42f 100644
--- a/app/workers/repository_import_worker.rb
+++ b/app/workers/repository_import_worker.rb
@@ -27,7 +27,6 @@ class RepositoryImportWorker
 
     project.import_finish
     project.save
-    project.satellite.create unless project.satellite.exists?
     ProjectCacheWorker.perform_async(project.id)
     Gitlab::BitbucketImport::KeyDeleter.new(project).execute if project.import_type == 'bitbucket'
   end
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 654de6238d0b184299a9c33956487ef80a6629fb..bd26ac1da209d452c4e4098edd9631578e6f5d5a 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -148,6 +148,7 @@ Settings.gitlab.default_projects_features['snippets']       = false if Settings.
 Settings.gitlab.default_projects_features['visibility_level']    = Settings.send(:verify_constant, Gitlab::VisibilityLevel, Settings.gitlab.default_projects_features['visibility_level'], Gitlab::VisibilityLevel::PRIVATE)
 Settings.gitlab['repository_downloads_path'] = File.absolute_path(Settings.gitlab['repository_downloads_path'] || 'tmp/repositories', Rails.root)
 Settings.gitlab['restricted_signup_domains'] ||= []
+Settings.gitlab['import_sources'] ||= ['github','bitbucket','gitlab','gitorious','google_code','git']
 
 #
 # Reply by email
diff --git a/config/routes.rb b/config/routes.rb
index 1166a4b3ebae33ad7221051987189b494f724b68..d7307a61ede75414c336cdff3e778c8e4cbcb912 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -463,8 +463,8 @@ Gitlab::Application.routes.draw do
           member do
             get :diffs
             get :commits
-            post :automerge
-            get :automerge_check
+            post :merge
+            get :merge_check
             get :ci_status
             post :toggle_subscription
           end
diff --git a/db/migrate/20150812080800_add_settings_import_sources.rb b/db/migrate/20150812080800_add_settings_import_sources.rb
new file mode 100644
index 0000000000000000000000000000000000000000..276d2fdb2b13f714629eb1566aa416d173bc5547
--- /dev/null
+++ b/db/migrate/20150812080800_add_settings_import_sources.rb
@@ -0,0 +1,11 @@
+require 'yaml'
+
+class AddSettingsImportSources < ActiveRecord::Migration
+  def change
+    unless column_exists?(:application_settings, :import_sources)
+      add_column :application_settings, :import_sources, :text
+      import_sources = YAML::dump(Settings.gitlab['import_sources'])
+      execute("update application_settings set import_sources = '#{import_sources}'")
+    end
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 0827e810f18e9e4ad3bc0831ccdb25b016f837d4..2b9a3e7f0116867d5a1896f8e7ddcf187e35d404 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -44,6 +44,7 @@ ActiveRecord::Schema.define(version: 20150818213832) do
     t.boolean  "user_oauth_applications",      default: true
     t.string   "after_sign_out_path"
     t.integer  "session_expire_delay",         default: 10080, null: false
+    t.text     "import_sources"
   end
 
   create_table "audit_events", force: true do |t|
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
index 541af487bb1fc71f34367ce0258408d77f790b62..c00d290371e032e45beea68e51236ea00f54db55 100644
--- a/doc/development/architecture.md
+++ b/doc/development/architecture.md
@@ -56,9 +56,9 @@ To serve repositories over SSH there's an add-on application called gitlab-shell
 
 A typical install of GitLab will be on GNU/Linux. It uses Nginx or Apache as a web front end to proxypass the Unicorn web server. By default, communication between Unicorn and the front end is via a Unix domain socket but forwarding requests via TCP is also supported. The web front end accesses `/home/git/gitlab/public` bypassing the Unicorn server to serve static pages, uploads (e.g. avatar images or attachments), and precompiled assets. GitLab serves web pages and a [GitLab API](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/api) using the Unicorn web server. It uses Sidekiq as a job queue which, in turn, uses redis as a non-persistent database backend for job information, meta data, and incoming jobs.
 
-The GitLab web app uses MySQL or PostgreSQL for persistent database information (e.g. users, permissions, issues, other meta data). GitLab stores the bare git repositories it serves in `/home/git/repositories` by default. It also keeps default branch and hook information with the bare repository. `/home/git/gitlab-satellites` keeps checked out repositories when performing actions such as a merge request, editing files in the web interface, etc.
+The GitLab web app uses MySQL or PostgreSQL for persistent database information (e.g. users, permissions, issues, other meta data). GitLab stores the bare git repositories it serves in `/home/git/repositories` by default. It also keeps default branch and hook information with the bare repository.
 
-The satellite repository is used by the web interface for editing repositories and the wiki which is also a git repository. When serving repositories over HTTP/HTTPS GitLab utilizes the GitLab API to resolve authorization and access as well as serving git objects.
+When serving repositories over HTTP/HTTPS GitLab utilizes the GitLab API to resolve authorization and access as well as serving git objects.
 
 The add-on component gitlab-shell serves repositories over SSH. It manages the SSH keys within `/home/git/.ssh/authorized_keys` which should not be manually edited. gitlab-shell accesses the bare repositories directly to serve git objects and communicates with redis to submit jobs to Sidekiq for GitLab to process. gitlab-shell queries the GitLab API to determine authorization and access.
 
@@ -129,7 +129,7 @@ Note: `/home/git/` is shorthand for `/home/git`.
 
 gitlabhq (includes Unicorn and Sidekiq logs)
 
-- `/home/git/gitlab/log/` contains `application.log`, `production.log`, `sidekiq.log`, `unicorn.stdout.log`, `githost.log`, `satellites.log`, and `unicorn.stderr.log` normally.
+- `/home/git/gitlab/log/` contains `application.log`, `production.log`, `sidekiq.log`, `unicorn.stdout.log`, `githost.log` and `unicorn.stderr.log` normally.
 
 gitlab-shell
 
diff --git a/doc/install/installation.md b/doc/install/installation.md
index c75e1d87862bf131cad04a7a7aa1c69dfa19df80..73e36fa7e51df31fa0a16699e76d67ae5ae893b3 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -216,10 +216,6 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
     sudo chmod -R u+rwX,go-w log/
     sudo chmod -R u+rwX tmp/
 
-    # Create directory for satellites
-    sudo -u git -H mkdir /home/git/gitlab-satellites
-    sudo chmod u+rwx,g=rx,o-rwx /home/git/gitlab-satellites
-
     # Make sure GitLab can write to the tmp/pids/ and tmp/sockets/ directories
     sudo chmod -R u+rwX tmp/pids/
     sudo chmod -R u+rwX tmp/sockets/
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index a78590d512a75a4ce2b4eb0a94952af9e28e0a97..aa0d03b75bcc45bd6db3f5d6f8ed17194b0e2e83 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -40,7 +40,7 @@ We love [JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/) but GitLab
 
 ### Storage
 
-The necessary hard drive space largely depends on the size of the repos you want to store in GitLab but as a *rule of thumb* you should have at least twice as much free space as all your repos combined take up. You need twice the storage because [GitLab satellites](structure.md) contain an extra copy of each repo.
+The necessary hard drive space largely depends on the size of the repos you want to store in GitLab but as a *rule of thumb* you should have at least as much free space as all your repos combined take up. 
 
 If you want to be flexible about growing your hard drive space in the future consider mounting it using LVM so you can add more hard drives when you need them.
 
@@ -113,4 +113,4 @@ On a very active server (10,000 active users) the Sidekiq process can use 1GB+ o
 
 ### Common UI problems with IE
 
-If you experience UI issues with Internet Explorer, please make sure that you have the `Compatibility View` mode disabled.
+If you experience UI issues with Internet Explorer, please make sure that you have the `Compatibility View` mode disabled.
\ No newline at end of file
diff --git a/doc/install/structure.md b/doc/install/structure.md
index 5c03f073c18c57094dc1d35d82f06eb318e4ebf1..d58b0040eefb80f92f7214f751734f27a467eb0d 100644
--- a/doc/install/structure.md
+++ b/doc/install/structure.md
@@ -6,16 +6,14 @@ This is the directory structure you will end up with following the instructions
     |   |-- git
     |       |-- .ssh
     |       |-- gitlab
-    |       |-- gitlab-satellites
     |       |-- gitlab-shell
     |       |-- repositories
 
 * `/home/git/.ssh` - contains openssh settings.  Specifically the `authorized_keys` file managed by gitlab-shell.
 * `/home/git/gitlab` - GitLab core software.
-* `/home/git/gitlab-satellites` - checked out repositories for merge requests and file editing from web UI.  This can be treated as a temporary files directory.
 * `/home/git/gitlab-shell` - Core add-on component of GitLab.  Maintains SSH cloning and other functionality.
 * `/home/git/repositories` - bare repositories for all projects organized by namespace.  This is where the git repositories which are pushed/pulled are maintained for all projects.  **This area is critical data for projects.  [Keep a backup](../raketasks/backup_restore.md)**
 
-*Note: the default locations for gitlab-satellites and repositories can be configured in `config/gitlab.yml` of GitLab and `config.yml` of gitlab-shell.*
+*Note: the default locations for repositories can be configured in `config/gitlab.yml` of GitLab and `config.yml` of gitlab-shell.*
 
 To see a more in-depth overview see the [GitLab architecture doc](../development/architecture.md).
diff --git a/doc/logs/logs.md b/doc/logs/logs.md
index 83c32b09253faea15241721afd0d40b925e56d31..27937e517644922d36930c923e1bd90f91c58e83 100644
--- a/doc/logs/logs.md
+++ b/doc/logs/logs.md
@@ -51,16 +51,6 @@ December 03, 2014 13:20 -> ERROR -> Command failed [1]: /usr/bin/git --git-dir=/
 error: failed to push some refs to '/Users/vsizov/gitlab-development-kit/repositories/gitlabhq/gitlab_git.git'
 ```
 
-#### satellites.log
-This file lives in `/var/log/gitlab/gitlab-rails/satellites.log` for omnibus package or in `/home/git/gitlab/log/satellites.log` for installations from the source.
-
-In some cases GitLab should perform write actions to git repository, for example when it is needed to merge the merge request or edit a file with online editor. If something went wrong you can look into this file to find out what exactly happened.
-```
-October 07, 2014 11:36: Failed to create satellite for Chesley Weimann III / project1817
-October 07, 2014 11:36: PID: 1872: git clone /Users/vsizov/gitlab-development-kit/gitlab/tmp/tests/repositories/conrad6841/gitlabhq.git /Users/vsizov/gitlab-development-kit/gitlab/tmp/tests/gitlab-satellites/conrad6841/gitlabhq
-October 07, 2014 11:36: PID: 1872: -> fatal: repository '/Users/vsizov/gitlab-development-kit/gitlab/tmp/tests/repositories/conrad6841/gitlabhq.git' does not exist
-```
-
 #### sidekiq.log
 This file lives in `/var/log/gitlab/gitlab-rails/sidekiq.log` for omnibus package or in `/home/git/gitlab/log/sidekiq.log` for installations from the source.
 
@@ -99,4 +89,4 @@ W, [2015-02-13T07:16:01.313000 #9094]  WARN -- : Unicorn::WorkerKiller send SIGQ
 I, [2015-02-13T07:16:01.530733 #9047]  INFO -- : reaped #<Process::Status: pid 9094 exit 0> worker=1
 I, [2015-02-13T07:16:01.534501 #13379]  INFO -- : worker=1 spawned pid=13379
 I, [2015-02-13T07:16:01.534848 #13379]  INFO -- : worker=1 ready
-```
\ No newline at end of file
+```
diff --git a/doc/profile/two_factor_authentication.md b/doc/profile/two_factor_authentication.md
index f60ce35d3e2f6ab953e5250eaf714e6b537dd8ce..a0e23c1586ccdd0152e4c900f071ad6f4f4e35d7 100644
--- a/doc/profile/two_factor_authentication.md
+++ b/doc/profile/two_factor_authentication.md
@@ -8,6 +8,10 @@ your phone.
 By enabling 2FA, the only way someone other than you can log into your account
 is to know your username and password *and* have access to your phone.
 
+#### Note
+When you enable 2FA, don't forget to back up your recovery codes. For your safety, if you
+lose your codes for GitLab.com, we can't disable or recover them.  
+
 ## Enabling 2FA
 
 **In GitLab:**
diff --git a/doc/raketasks/maintenance.md b/doc/raketasks/maintenance.md
index 69171cd17654f83b6a98d5abcfdc5f373fdf9da8..d9dce2af480ca40ab9d3c1f6b5a8e89087e94acf 100644
--- a/doc/raketasks/maintenance.md
+++ b/doc/raketasks/maintenance.md
@@ -105,24 +105,11 @@ Log directory writable? ... yes
 Tmp directory writable? ... yes
 Init script exists? ... yes
 Init script up-to-date? ... yes
-Projects have satellites? ... yes
 Redis version >= 2.0.0? ... yes
 
 Checking GitLab ... Finished
 ```
 
-## (Re-)Create satellite repositories
-
-This will create satellite repositories for all your projects.
-
-If necessary, remove the `repo_satellites` directory and rerun the commands below.
-
-```
-sudo -u git -H mkdir -p /home/git/gitlab-satellites
-sudo -u git -H bundle exec rake gitlab:satellites:create RAILS_ENV=production
-sudo chmod u+rwx,g=rx,o-rwx /home/git/gitlab-satellites
-```
-
 ## Rebuild authorized_keys file
 
 In some case it is necessary to rebuild the `authorized_keys` file.
diff --git a/doc/release/monthly.md b/doc/release/monthly.md
index b10e7420675d67477e7247dd4b0b18f52c004fe4..12d6a84b68e5ec4ac7c62174a50beddf6f7e06be 100644
--- a/doc/release/monthly.md
+++ b/doc/release/monthly.md
@@ -156,6 +156,7 @@ Tweet about the RC release:
 1. Also check the CI changelog
 1. Add a proposed tweet text to the blog post WIP MR description.
 1. Create a WIP MR for the blog post
+1. Make sure merge request title starts with `WIP` so it can not be accidently merged until ready.
 1. Ask Dmitriy (or a team member with OS X) to add screenshots to the WIP MR.
 1. Decide with core team who will be the MVP user.
 1. Create WIP MR for adding MVP to MVP page on website
diff --git a/doc/workflow/README.md b/doc/workflow/README.md
index 3915198ad2a3ee755807ffb3e63cbb9bd1aafa7f..5b8d72dfd340f60368827d46844cbf4cc595a2f8 100644
--- a/doc/workflow/README.md
+++ b/doc/workflow/README.md
@@ -13,4 +13,5 @@
 - [Project users](add-user/add-user.md)
 - [Protected branches](protected_branches.md)
 - [Web Editor](web_editor.md)
+- [Merge Requests](merge_requests.md)
 - ["Work In Progress" Merge Requests](wip_merge_requests.md)
diff --git a/doc/workflow/merge_requests.md b/doc/workflow/merge_requests.md
new file mode 100644
index 0000000000000000000000000000000000000000..751e19da7f19a5820bb40e8b4f2a79eb8bb7cc0c
--- /dev/null
+++ b/doc/workflow/merge_requests.md
@@ -0,0 +1,40 @@
+# Merge Requests
+
+Merge requests allow you to exchange changes you made to source code
+
+## Checkout merge requests locally
+
+Locate the section for your GitLab remote in the `.git/config` file. It looks like this:
+
+```
+[remote "origin"]
+  url = https://gitlab.com/gitlab-org/gitlab-ce.git
+  fetch = +refs/heads/*:refs/remotes/origin/*
+```
+
+Now add the line `fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*` to this section. 
+
+It should looks like this: 
+
+```
+[remote "origin"]
+  url = https://gitlab.com/gitlab-org/gitlab-ce.git
+  fetch = +refs/heads/*:refs/remotes/origin/*
+  fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*
+```
+
+Now you can fetch all the merge requests requests:
+
+```
+$ git fetch origin
+From https://gitlab.com/gitlab-org/gitlab-ce.git
+ * [new ref]         refs/merge-requests/1/head -> origin/merge-requests/1
+ * [new ref]         refs/merge-requests/2/head -> origin/merge-requests/2
+...
+```
+
+To check out a particular merge request:
+
+```
+$ git checkout origin/merge-requests/1
+```
diff --git a/features/admin/projects.feature b/features/admin/projects.feature
index a6c3d6b78222b87b45503faa33cbb82ea186e967..f7cec04eb75e7db842077385584dbbb18a1bfb51 100644
--- a/features/admin/projects.feature
+++ b/features/admin/projects.feature
@@ -4,9 +4,18 @@ Feature: Admin Projects
     Given I sign in as an admin
     And there are projects in system
 
-  Scenario: Projects list
+  Scenario: I should see non-archived projects in the list
+    Given archived project "Archive"
     When I visit admin projects page
+    Then I should see all non-archived projects
+    And I should not see project "Archive"
+
+  Scenario: I should see all projects in the list
+    Given archived project "Archive"
+    When I visit admin projects page
+    And I check "Show archived projects"
     Then I should see all projects
+    And I should see "archived" label
 
   Scenario: Projects show
     When I visit admin projects page
diff --git a/features/dashboard/new_project.feature b/features/dashboard/new_project.feature
index 431dc4ccfcb258c50a042274bb53d40832049b3b..bbd82a85e3a719b44da8cb24a07e6cc089b8ef29 100644
--- a/features/dashboard/new_project.feature
+++ b/features/dashboard/new_project.feature
@@ -4,10 +4,27 @@ Background:
   Given I sign in as a user
   And I own project "Shop"
   And I visit dashboard page
+  And I click "New project" link
 
   @javascript
   Scenario: I should see New projects page
-  Given I click "New project" link
   Then I see "New project" page
+  Then I see all possible import optios
+
+  @javascript
+  Scenario: I should see instructions on how to import from Git URL
+  Given I see "New project" page
+  When I click on "Any repo by URL"
+  Then I see instructions on how to import from Git URL
+
+  @javascript
+  Scenario: I should see instructions on how to import from GitHub
+  Given I see "New project" page
   When I click on "Import project from GitHub"
   Then I see instructions on how to import from GitHub
+
+  @javascript
+  Scenario: I should see Google Code import page
+  Given I see "New project" page
+  When I click on "Google Code"
+  Then I redirected to Google Code import page
diff --git a/features/explore/projects.feature b/features/explore/projects.feature
index a1b2972267871f314fb427560d9d4038ab2e7476..5d3870827f55d480fcead134df7147dfafe4d6d4 100644
--- a/features/explore/projects.feature
+++ b/features/explore/projects.feature
@@ -6,10 +6,12 @@ Feature: Explore Projects
     And private project "Enterprise"
 
   Scenario: I visit public area
+    Given archived project "Archive"
     When I visit the public projects area
     Then I should see project "Community"
     And I should not see project "Internal"
     And I should not see project "Enterprise"
+    And I should not see project "Archive"
 
   Scenario: I visit public project page
     When I visit project "Community" page
@@ -37,11 +39,13 @@ Feature: Explore Projects
     And I should see empty public project details with ssh clone info
 
   Scenario: I visit public area as user
-    Given I sign in as a user
+    Given archived project "Archive"
+    And I sign in as a user
     When I visit the public projects area
     Then I should see project "Community"
     And I should see project "Internal"
     And I should not see project "Enterprise"
+    And I should not see project "Archive"
 
   Scenario: I visit internal project page as user
     Given I sign in as a user
@@ -102,15 +106,20 @@ Feature: Explore Projects
     Then I should see list of merge requests for "Internal" project
 
   Scenario: Trending page
-    Given I sign in as a user
+    Given archived project "Archive"
+    And project "Archive" has comments
+    And I sign in as a user
     And project "Community" has comments
     When I visit the explore trending projects
     Then I should see project "Community"
     And I should not see project "Internal"
     And I should not see project "Enterprise"
+    And I should not see project "Archive"
 
   Scenario: Most starred page
-    Given I sign in as a user
+    Given archived project "Archive"
+    And I sign in as a user
     When I visit the explore starred projects
     Then I should see project "Community"
     And I should see project "Internal"
+    And I should see project "Archive"
diff --git a/features/groups.feature b/features/groups.feature
index 299e846edb07083d0fd858fc6e0775ce4cd6dee8..d5272fdddcfcb0808d781d8a7b2aefda8eff0193 100644
--- a/features/groups.feature
+++ b/features/groups.feature
@@ -152,3 +152,10 @@ Feature: Groups
     And I click on one group milestone
     Then I should see group milestone with descriptions and expiry date
     And I should see group milestone with all issues and MRs assigned to that milestone
+
+  # Group projects in settings
+  Scenario: I should see all projects in the project list in settings
+    Given Group "Owned" has archived project
+    When I visit group "Owned" projects page
+    Then I should see group "Owned" projects list
+    And I should see "archived" label
diff --git a/features/steps/admin/projects.rb b/features/steps/admin/projects.rb
index 655f18952799f9f6b91a4fc333cbe778fc5282ce..17233f89f38adb2fc2332c1b11e801a4216eca67 100644
--- a/features/steps/admin/projects.rb
+++ b/features/steps/admin/projects.rb
@@ -2,6 +2,13 @@ class Spinach::Features::AdminProjects < Spinach::FeatureSteps
   include SharedAuthentication
   include SharedPaths
   include SharedAdmin
+  include SharedProject
+
+  step 'I should see all non-archived projects' do
+    Project.non_archived.each do |p|
+      expect(page).to have_content p.name_with_namespace
+    end
+  end
 
   step 'I should see all projects' do
     Project.all.each do |p|
@@ -9,6 +16,15 @@ class Spinach::Features::AdminProjects < Spinach::FeatureSteps
     end
   end
 
+  step 'I check "Show archived projects"' do
+    page.check 'Show archived projects'
+    click_button "Search"
+  end
+
+  step 'I should see "archived" label' do
+    expect(page).to have_xpath("//span[@class='label label-warning']", text: 'archived')
+  end
+
   step 'I click on first project' do
     click_link Project.first.name_with_namespace
   end
diff --git a/features/steps/dashboard/help.rb b/features/steps/dashboard/help.rb
index 86ab31a58aba4eb45aa51cffdc2b328c3e3a2ecf..800e869533e927f12fb2bd99e1db30535e69f30e 100644
--- a/features/steps/dashboard/help.rb
+++ b/features/steps/dashboard/help.rb
@@ -16,6 +16,6 @@ class Spinach::Features::DashboardHelp < Spinach::FeatureSteps
   end
 
   step 'Header "Rebuild project satellites" should have correct ids and links' do
-    header_should_have_correct_id_and_link(2, '(Re-)Create satellite repositories', 're-create-satellite-repositories', '.documentation')
+    header_should_have_correct_id_and_link(2, 'Check GitLab configuration', 'check-gitlab-configuration', '.documentation')
   end
 end
diff --git a/features/steps/dashboard/merge_requests.rb b/features/steps/dashboard/merge_requests.rb
index cec8d06adee62b66a48bc7eb7803e8a0799c25e9..28c8c6b6015147ca49946968163ea9d6dcda01c5 100644
--- a/features/steps/dashboard/merge_requests.rb
+++ b/features/steps/dashboard/merge_requests.rb
@@ -66,7 +66,7 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps
 
   def authored_merge_request
     @authored_merge_request ||= create :merge_request,
-                                  source_branch: 'simple_merge_request',
+                                  source_branch: 'markdown',
                                   author: current_user,
                                   target_project: project,
                                   source_project: project
@@ -74,14 +74,14 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps
 
   def other_merge_request
     @other_merge_request ||= create :merge_request,
-                              source_branch: '2_3_notes_fix',
+                              source_branch: 'fix',
                               target_project: project,
                               source_project: project
   end
 
   def authored_merge_request_from_fork
     @authored_merge_request_from_fork ||= create :merge_request,
-                                            source_branch: 'basic_page',
+                                            source_branch: 'feature_conflict',
                                             author: current_user,
                                             target_project: public_project,
                                             source_project: forked_project
@@ -89,7 +89,7 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps
 
   def assigned_merge_request_from_fork
     @assigned_merge_request_from_fork ||= create :merge_request,
-                                            source_branch: 'basic_page_fix',
+                                            source_branch: 'markdown',
                                             assignee: current_user,
                                             target_project: public_project,
                                             source_project: forked_project
diff --git a/features/steps/dashboard/new_project.rb b/features/steps/dashboard/new_project.rb
index d4440c1fb4d088c46a35f74843f8718dee07a570..1e09162a5b513db22c97633c1273f524da9e9c5b 100644
--- a/features/steps/dashboard/new_project.rb
+++ b/features/steps/dashboard/new_project.rb
@@ -13,8 +13,17 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps
     expect(page).to have_content('Project path')
   end
 
+  step 'I see all possible import optios' do
+    expect(page).to have_link('GitHub')
+    expect(page).to have_link('Bitbucket')
+    expect(page).to have_link('GitLab.com')
+    expect(page).to have_link('Gitorious.org')
+    expect(page).to have_link('Google Code')
+    expect(page).to have_link('Any repo by URL')
+  end
+
   step 'I click on "Import project from GitHub"' do
-    first('.how_to_import_link').click
+    first('.import_github').click
   end
 
   step 'I see instructions on how to import from GitHub' do
@@ -26,4 +35,24 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps
       expect(element).not_to be_visible unless element == github_modal
     end
   end
+
+  step 'I click on "Any repo by URL"' do
+    first('.import_git').click
+  end
+
+  step 'I see instructions on how to import from Git URL' do
+    git_import_instructions = first('.js-toggle-content')
+    expect(git_import_instructions).to be_visible
+    expect(git_import_instructions).to have_content "Git repository URL"
+    expect(git_import_instructions).to have_content "The repository must be accessible over HTTP(S). If it is not publicly accessible, you can add authentication information to the URL:"
+  end
+
+  step 'I click on "Google Code"' do
+    first('.import_google_code').click
+  end
+
+  step 'I redirected to Google Code import page' do
+    expect(current_path).to eq new_import_google_code_path
+  end
+
 end
diff --git a/features/steps/groups.rb b/features/steps/groups.rb
index 46e1f4d0990ae3cc3bd543e331278b96f459c65d..18a1c4d32ce3761b3cef4def9749213933d2289d 100644
--- a/features/steps/groups.rb
+++ b/features/steps/groups.rb
@@ -226,6 +226,15 @@ class Spinach::Features::Groups < Spinach::FeatureSteps
     expect(page).to have_link(@mr3.title, href: namespace_project_merge_request_path(@project3.namespace, @project3, @mr3))
   end
 
+  step 'Group "Owned" has archived project' do
+    group = Group.find_by(name: 'Owned')
+    create(:project, namespace: group, archived: true, path: "archived-project")
+  end
+
+  step 'I should see "archived" label' do
+    expect(page).to have_xpath("//span[@class='label label-warning']", text: 'archived')
+  end
+
   protected
 
   def assigned_to_me(key)
diff --git a/features/steps/project/forked_merge_requests.rb b/features/steps/project/forked_merge_requests.rb
index 3e97e84d116164b55ddec7002c6233703f1cd1f6..2a333222fb29b024a6e0e7b3ad164d8a04f5ca1a 100644
--- a/features/steps/project/forked_merge_requests.rb
+++ b/features/steps/project/forked_merge_requests.rb
@@ -9,7 +9,6 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps
     @project = Project.find_by(name: "Shop")
     @project ||= create(:project, name: "Shop")
     @project.team << [@user, :reporter]
-    @project.ensure_satellite_exists
   end
 
   step 'I have a project forked off of "Shop" called "Forked Shop"' do
diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb
index 04784207a1af91c9ed1b81f27aa5f1ab44c11a97..778dce06359603555cdc23b0fc25304afcb7e8fd 100644
--- a/features/steps/project/merge_requests.rb
+++ b/features/steps/project/merge_requests.rb
@@ -198,15 +198,10 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
   end
 
   step 'merge request "Bug NS-05" is mergeable' do
-    merge_request.project.satellite.create
     merge_request.mark_as_mergeable
   end
 
   step 'I accept this merge request' do
-    Gitlab::Satellite::MergeAction.any_instance.stub(
-      merge!: true,
-    )
-
     page.within '.mr-state-widget' do
       click_button "Accept Merge Request"
     end
diff --git a/features/steps/shared/active_tab.rb b/features/steps/shared/active_tab.rb
index 72d873caa5734a0eeb24795d792ac0436adeb0dd..92e099315d81a5b26f120a0b03868ae6d0e31879 100644
--- a/features/steps/shared/active_tab.rb
+++ b/features/steps/shared/active_tab.rb
@@ -26,7 +26,7 @@ module SharedActiveTab
   end
 
   step 'the active main tab should be Home' do
-    ensure_active_main_tab('Your Projects')
+    ensure_active_main_tab('Projects')
   end
 
   step 'the active main tab should be Projects' do
diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb
index bb0cd9ac105baff99b1ea378ea82e1bbbe87f147..ca8fbb49101b32e43ba7af3a5cdcb893cd419a2b 100644
--- a/features/steps/shared/paths.rb
+++ b/features/steps/shared/paths.rb
@@ -39,6 +39,10 @@ module SharedPaths
     visit edit_group_path(Group.find_by(name: "Owned"))
   end
 
+  step 'I visit group "Owned" projects page' do
+    visit projects_group_path(Group.find_by(name: "Owned"))
+  end
+
   step 'I visit group "Guest" page' do
     visit group_path(Group.find_by(name: "Guest"))
   end
diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb
index 9ee2e5dfbed6c23f7b6f3c11975755157d887b7b..ccbe8f96a4c0256c7300d3942cbd4c4b4c8b9468 100644
--- a/features/steps/shared/project.rb
+++ b/features/steps/shared/project.rb
@@ -92,6 +92,29 @@ module SharedProject
     @project ||= Project.first
   end
 
+  # ----------------------------------------
+  # Visibility of archived project
+  # ----------------------------------------
+
+  step 'archived project "Archive"' do
+    create :project, :public, archived: true, name: 'Archive'
+  end
+
+  step 'I should not see project "Archive"' do
+    project = Project.find_by(name: "Archive")
+    expect(page).not_to have_content project.name_with_namespace
+  end
+
+  step 'I should see project "Archive"' do
+    project = Project.find_by(name: "Archive")
+    expect(page).to have_content project.name_with_namespace
+  end
+
+  step 'project "Archive" has comments' do
+    project = Project.find_by(name: "Archive")
+    2.times { create(:note_on_issue, project: project) }
+  end
+
   # ----------------------------------------
   # Visibility level
   # ----------------------------------------
diff --git a/features/support/env.rb b/features/support/env.rb
index 672251af084972a12cb8e2cc130112bd73c34e63..62c80b9c94884b949f8df13f3250d2a2f39376ea 100644
--- a/features/support/env.rb
+++ b/features/support/env.rb
@@ -28,5 +28,9 @@ Spinach.hooks.before_run do
   RSpec::Mocks.setup
   TestEnv.init(mailer: false)
 
+  # skip pre-receive hook check so we can use
+  # web editor and merge
+  TestEnv.disable_pre_receive
+
   include FactoryGirl::Syntax::Methods
 end
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 09d231af41b75ce4c947dad0c6c9985085d22697..1f9dd6bc152a6c1bda336462234e6c10893654b6 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -221,6 +221,7 @@ module API
       expose(:line) { |note| note.diff_new_line }
       expose(:line_type) { |note| note.diff_line_type }
       expose :author, using: Entities::UserBasic
+      expose :created_at
     end
 
     class Event < Grape::Entity
diff --git a/lib/api/files.rb b/lib/api/files.rb
index 83581cd3990fe522139ad3ec0c0db335c8aca24a..308c84dd13586c6d5d09d504fa4d3a14a452e7aa 100644
--- a/lib/api/files.rb
+++ b/lib/api/files.rb
@@ -3,6 +3,26 @@ module API
   class Files < Grape::API
     before { authenticate! }
 
+    helpers do
+      def commit_params(attrs)
+        {
+          file_path: attrs[:file_path],
+          current_branch: attrs[:branch_name],
+          target_branch: attrs[:branch_name],
+          commit_message: attrs[:commit_message],
+          file_content: attrs[:content],
+          file_content_encoding: attrs[:encoding]
+        }
+      end
+
+      def commit_response(attrs)
+        {
+          file_path: attrs[:file_path],
+          branch_name: attrs[:branch_name],
+        }
+      end
+    end
+
     resource :projects do
       # Get file from repository
       # File content is Base64 encoded
@@ -73,17 +93,11 @@ module API
 
         required_attributes! [:file_path, :branch_name, :content, :commit_message]
         attrs = attributes_for_keys [:file_path, :branch_name, :content, :commit_message, :encoding]
-        branch_name = attrs.delete(:branch_name)
-        file_path = attrs.delete(:file_path)
-        result = ::Files::CreateService.new(user_project, current_user, attrs, branch_name, file_path).execute
+        result = ::Files::CreateService.new(user_project, current_user, commit_params(attrs)).execute
 
         if result[:status] == :success
           status(201)
-
-          {
-            file_path: file_path,
-            branch_name: branch_name
-          }
+          commit_response(attrs)
         else
           render_api_error!(result[:message], 400)
         end
@@ -105,17 +119,11 @@ module API
 
         required_attributes! [:file_path, :branch_name, :content, :commit_message]
         attrs = attributes_for_keys [:file_path, :branch_name, :content, :commit_message, :encoding]
-        branch_name = attrs.delete(:branch_name)
-        file_path = attrs.delete(:file_path)
-        result = ::Files::UpdateService.new(user_project, current_user, attrs, branch_name, file_path).execute
+        result = ::Files::UpdateService.new(user_project, current_user, commit_params(attrs)).execute
 
         if result[:status] == :success
           status(200)
-
-          {
-            file_path: file_path,
-            branch_name: branch_name
-          }
+          commit_response(attrs)
         else
           http_status = result[:http_status] || 400
           render_api_error!(result[:message], http_status)
@@ -138,17 +146,11 @@ module API
 
         required_attributes! [:file_path, :branch_name, :commit_message]
         attrs = attributes_for_keys [:file_path, :branch_name, :commit_message]
-        branch_name = attrs.delete(:branch_name)
-        file_path = attrs.delete(:file_path)
-        result = ::Files::DeleteService.new(user_project, current_user, attrs, branch_name, file_path).execute
+        result = ::Files::DeleteService.new(user_project, current_user, commit_params(attrs)).execute
 
         if result[:status] == :success
           status(200)
-
-          {
-            file_path: file_path,
-            branch_name: branch_name
-          }
+          commit_response(attrs)
         else
           render_api_error!(result[:message], 400)
         end
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index ce21c699e8fc0259b7bfb2627414d7cdecc77ca1..7412274b0454f89d11dca509ed167fc3e1e6f1d3 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -198,7 +198,11 @@ module API
 
           if merge_request.open? && !merge_request.work_in_progress?
             if merge_request.can_be_merged?
-              merge_request.automerge!(current_user, params[:merge_commit_message] || merge_request.merge_commit_message)
+              commit_message = params[:merge_commit_message] || merge_request.merge_commit_message
+
+              ::MergeRequests::MergeService.new(merge_request.target_project, current_user).
+                execute(merge_request, commit_message)
+
               present merge_request, with: Entities::MergeRequest
             else
               render_api_error!('Branch cannot be merged', 405)
diff --git a/lib/gitlab.rb b/lib/gitlab.rb
index 5fc1862c3e931f3ec7ab8907c0ce25f192c67a52..6108697bc2012e22d96896194df7c7cadbc5b125 100644
--- a/lib/gitlab.rb
+++ b/lib/gitlab.rb
@@ -1,5 +1,4 @@
 require 'gitlab/git'
 
 module Gitlab
-  autoload :Satellite, 'gitlab/satellite/satellite'
 end
diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb
index 172d4902add336e73894828004322d14a06969ab..14ee4701e7bb9faa44e664c9c36124a91efd4305 100644
--- a/lib/gitlab/backend/shell.rb
+++ b/lib/gitlab/backend/shell.rb
@@ -217,20 +217,6 @@ module Gitlab
       FileUtils.mv(full_path(old_name), full_path(new_name))
     end
 
-    # Remove GitLab Satellites for provided path (namespace or repo dir)
-    #
-    # Ex.
-    #   rm_satellites("gitlab")
-    #
-    #   rm_satellites("gitlab/gitlab-ci.git")
-    #
-    def rm_satellites(path)
-      raise ArgumentError.new("Path can't be blank") if path.blank?
-
-      satellites_path = File.join(Gitlab.config.satellites.path, path)
-      FileUtils.rm_r(satellites_path, force: true)
-    end
-
     def url_to_repo(path)
       Gitlab.config.gitlab_shell.ssh_path_prefix + "#{path}.git"
     end
diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb
index 931d51c55d3f6348c65343d0b67cd711e85b673e..1a2a50a14d0072a80231bc2814d495ba8d357037 100644
--- a/lib/gitlab/current_settings.rb
+++ b/lib/gitlab/current_settings.rb
@@ -22,7 +22,8 @@ module Gitlab
         sign_in_text: Settings.extra['sign_in_text'],
         restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'],
         max_attachment_size: Settings.gitlab['max_attachment_size'],
-        session_expire_delay: Settings.gitlab['session_expire_delay']
+        session_expire_delay: Settings.gitlab['session_expire_delay'],
+        import_sources: Settings.gitlab['import_sources']
       )
     end
   end
diff --git a/lib/gitlab/git/hook.rb b/lib/gitlab/git/hook.rb
new file mode 100644
index 0000000000000000000000000000000000000000..dd393fe09d201e8739e3fc5224061565fb36a844
--- /dev/null
+++ b/lib/gitlab/git/hook.rb
@@ -0,0 +1,59 @@
+module Gitlab
+  module Git
+    class Hook
+      attr_reader :name, :repo_path, :path
+
+      def initialize(name, repo_path)
+        @name = name
+        @repo_path = repo_path
+        @path = File.join(repo_path.strip, 'hooks', name)
+      end
+
+      def exists?
+        File.exist?(path)
+      end
+
+      def trigger(gl_id, oldrev, newrev, ref)
+        return true unless exists?
+
+        changes = [oldrev, newrev, ref].join(" ")
+
+        # function  will return true if succesful
+        exit_status = false
+
+        vars = {
+          'GL_ID' => gl_id,
+          'PWD' => repo_path
+        }
+
+        options = {
+          chdir: repo_path
+        }
+
+        Open3.popen2(vars, path, options) do |stdin, _, wait_thr|
+          exit_status = true
+          stdin.sync = true
+
+          # in git, pre- and post- receive hooks may just exit without
+          # reading stdin. We catch the exception to avoid a broken pipe
+          # warning
+          begin
+            # inject all the changes as stdin to the hook
+            changes.lines do |line|
+              stdin.puts line
+            end
+          rescue Errno::EPIPE
+          end
+
+          stdin.close
+
+          unless wait_thr.value == 0
+            exit_status = false
+          end
+        end
+
+        exit_status
+      end
+    end
+  end
+end
diff --git a/lib/gitlab/import_sources.rb b/lib/gitlab/import_sources.rb
new file mode 100644
index 0000000000000000000000000000000000000000..991b70aab6a3756b450abf1a21f07cf4c43066ba
--- /dev/null
+++ b/lib/gitlab/import_sources.rb
@@ -0,0 +1,29 @@
+# Gitlab::ImportSources module
+#
+# Define import sources that can be used
+# during the creation of new project
+#
+module Gitlab
+  module ImportSources
+    extend CurrentSettings
+
+    class << self
+      def values
+        options.values
+      end
+
+      def options
+        {
+          'GitHub'          => 'github',
+          'Bitbucket'       => 'bitbucket',
+          'GitLab.com'      => 'gitlab',
+          'Gitorious.org'   => 'gitorious',
+          'Google Code'     => 'google_code',
+          'Any repo by URL' => 'git',
+        }
+      end
+
+    end
+
+  end
+end
diff --git a/lib/gitlab/satellite/action.rb b/lib/gitlab/satellite/action.rb
deleted file mode 100644
index 489070f1a3f4dcecc2fde5e530ec2230b2e1e420..0000000000000000000000000000000000000000
--- a/lib/gitlab/satellite/action.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-module Gitlab
-  module Satellite
-    class Action
-      DEFAULT_OPTIONS = { git_timeout: Gitlab.config.satellites.timeout.seconds }
-
-      attr_accessor :options, :project, :user
-
-      def initialize(user, project, options = {})
-        @options = DEFAULT_OPTIONS.merge(options)
-        @project = project
-        @user = user
-      end
-
-      protected
-
-      # * Sets a 30s timeout for Git
-      # * Locks the satellite repo
-      # * Yields the prepared satellite repo
-      def in_locked_and_timed_satellite
-        Gitlab::ShellEnv.set_env(user)
-
-        Grit::Git.with_timeout(options[:git_timeout]) do
-          project.satellite.lock do
-            return yield project.satellite.repo
-          end
-        end
-      rescue Errno::ENOMEM => ex
-        return handle_exception(ex)
-      rescue Grit::Git::GitTimeout => ex
-        return handle_exception(ex)
-      ensure
-        Gitlab::ShellEnv.reset_env
-      end
-
-      # * Recreates the satellite
-      # * Sets up Git variables for the user
-      #
-      # Note: use this within #in_locked_and_timed_satellite
-      def prepare_satellite!(repo)
-        project.satellite.clear_and_update!
-
-        if user
-          repo.config['user.name'] = user.name
-          repo.config['user.email'] = user.email
-        end
-      end
-
-      def default_options(options = {})
-        { raise: true, timeout: true }.merge(options)
-      end
-
-      def handle_exception(exception)
-        Gitlab::GitLogger.error(exception.message)
-        false
-      end
-    end
-  end
-end
diff --git a/lib/gitlab/satellite/compare_action.rb b/lib/gitlab/satellite/compare_action.rb
deleted file mode 100644
index 46c98a8f4cab479a6bfa2f5ee6483864403fd807..0000000000000000000000000000000000000000
--- a/lib/gitlab/satellite/compare_action.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-module Gitlab
-  module Satellite
-    class BranchesWithoutParent < StandardError; end
-
-    class CompareAction < Action
-      def initialize(user, target_project, target_branch, source_project, source_branch)
-        super user, target_project
-
-        @target_project, @target_branch = target_project, target_branch
-        @source_project, @source_branch = source_project, source_branch
-      end
-
-      # Compare 2 repositories and return Gitlab::CompareResult object
-      def result
-        in_locked_and_timed_satellite do |target_repo|
-          prepare_satellite!(target_repo)
-          update_satellite_source_and_target!(target_repo)
-
-          Gitlab::CompareResult.new(compare(target_repo))
-        end
-      rescue Grit::Git::CommandFailed => ex
-        raise BranchesWithoutParent
-      end
-
-      private
-
-      # Assumes a satellite exists that is a fresh clone of the projects repo, prepares satellite for diffs
-      def update_satellite_source_and_target!(target_repo)
-        target_repo.remote_add('source', @source_project.repository.path_to_repo)
-        target_repo.remote_fetch('source')
-      rescue Grit::Git::CommandFailed => ex
-        handle_exception(ex)
-      end
-
-      def compare(repo)
-        @compare ||= Gitlab::Git::Compare.new(
-          Gitlab::Git::Repository.new(repo.path),
-          "origin/#{@target_branch}",
-          "source/#{@source_branch}"
-        )
-      end
-    end
-  end
-end
diff --git a/lib/gitlab/satellite/files/delete_file_action.rb b/lib/gitlab/satellite/files/delete_file_action.rb
deleted file mode 100644
index 0d37b9dea8502e765aed57cfedfea514f29dcc9e..0000000000000000000000000000000000000000
--- a/lib/gitlab/satellite/files/delete_file_action.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-require_relative 'file_action'
-
-module Gitlab
-  module Satellite
-    class DeleteFileAction < FileAction
-      # Deletes file and creates a new commit for it
-      #
-      # Returns false if committing the change fails
-      # Returns false if pushing from the satellite to bare repo failed or was rejected
-      # Returns true otherwise
-      def commit!(content, commit_message)
-        in_locked_and_timed_satellite do |repo|
-          prepare_satellite!(repo)
-
-          # create target branch in satellite at the corresponding commit from bare repo
-          repo.git.checkout({ raise: true, timeout: true, b: true }, ref, "origin/#{ref}")
-
-          # update the file in the satellite's working dir
-          file_path_in_satellite = File.join(repo.working_dir, file_path)
-
-          # Prevent relative links
-          unless safe_path?(file_path_in_satellite)
-            Gitlab::GitLogger.error("FileAction: Relative path not allowed")
-            return false
-          end
-
-          File.delete(file_path_in_satellite)
-
-          # add removed file
-          repo.remove(file_path_in_satellite)
-
-          # commit the changes
-          # will raise CommandFailed when commit fails
-          repo.git.commit(raise: true, timeout: true, a: true, m: commit_message)
-
-
-          # push commit back to bare repo
-          # will raise CommandFailed when push fails
-          repo.git.push({ raise: true, timeout: true }, :origin, ref)
-
-          # everything worked
-          true
-        end
-      rescue Grit::Git::CommandFailed => ex
-        Gitlab::GitLogger.error(ex.message)
-        false
-      end
-    end
-  end
-end
diff --git a/lib/gitlab/satellite/files/edit_file_action.rb b/lib/gitlab/satellite/files/edit_file_action.rb
deleted file mode 100644
index 3cb9c0b5ecbceed9529812162d235befca60ffb7..0000000000000000000000000000000000000000
--- a/lib/gitlab/satellite/files/edit_file_action.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-require_relative 'file_action'
-
-module Gitlab
-  module Satellite
-    # GitLab server-side file update and commit
-    class EditFileAction < FileAction
-      # Updates the files content and creates a new commit for it
-      #
-      # Returns false if the ref has been updated while editing the file
-      # Returns false if committing the change fails
-      # Returns false if pushing from the satellite to bare repo failed or was rejected
-      # Returns true otherwise
-      def commit!(content, commit_message, encoding, new_branch = nil)
-        in_locked_and_timed_satellite do |repo|
-          prepare_satellite!(repo)
-
-          # create target branch in satellite at the corresponding commit from bare repo
-          begin
-            repo.git.checkout({ raise: true, timeout: true, b: true }, ref, "origin/#{ref}")
-          rescue Grit::Git::CommandFailed => ex
-            log_and_raise(CheckoutFailed, ex.message)
-          end
-
-          # update the file in the satellite's working dir
-          file_path_in_satellite = File.join(repo.working_dir, file_path)
-
-          # Prevent relative links
-          unless safe_path?(file_path_in_satellite)
-            Gitlab::GitLogger.error("FileAction: Relative path not allowed")
-            return false
-          end
-
-          # Write file
-          write_file(file_path_in_satellite, content, encoding)
-
-          # commit the changes
-          # will raise CommandFailed when commit fails
-          begin
-            repo.git.commit(raise: true, timeout: true, a: true, m: commit_message)
-          rescue Grit::Git::CommandFailed => ex
-            log_and_raise(CommitFailed, ex.message)
-          end
-
-
-          target_branch = new_branch.present? ? "#{ref}:#{new_branch}" : ref
-
-          # push commit back to bare repo
-          # will raise CommandFailed when push fails
-          begin
-            repo.git.push({ raise: true, timeout: true }, :origin, target_branch)
-          rescue Grit::Git::CommandFailed => ex
-            log_and_raise(PushFailed, ex.message)
-          end
-
-          # everything worked
-          true
-        end
-      end
-
-      private
-
-      def log_and_raise(errorClass, message)
-        Gitlab::GitLogger.error(message)
-        raise(errorClass, message)
-      end
-    end
-  end
-end
diff --git a/lib/gitlab/satellite/files/file_action.rb b/lib/gitlab/satellite/files/file_action.rb
deleted file mode 100644
index 6446b14568a5de087d3e0cbbf91506dacf24fa74..0000000000000000000000000000000000000000
--- a/lib/gitlab/satellite/files/file_action.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-module Gitlab
-  module Satellite
-    class FileAction < Action
-      attr_accessor :file_path, :ref
-
-      def initialize(user, project, ref, file_path)
-        super user, project
-        @file_path = file_path
-        @ref = ref
-      end
-
-      def safe_path?(path)
-        File.absolute_path(path) == path
-      end
-
-      def write_file(abs_file_path, content, file_encoding = 'text')
-        if file_encoding == 'base64'
-          File.open(abs_file_path, 'wb') { |f| f.write(Base64.decode64(content)) }
-        else
-          File.open(abs_file_path, 'w') { |f| f.write(content) }
-        end
-      end
-    end
-  end
-end
diff --git a/lib/gitlab/satellite/files/new_file_action.rb b/lib/gitlab/satellite/files/new_file_action.rb
deleted file mode 100644
index 724dfa0d042e1a80376a40dad4a34967998fdf5e..0000000000000000000000000000000000000000
--- a/lib/gitlab/satellite/files/new_file_action.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-require_relative 'file_action'
-
-module Gitlab
-  module Satellite
-    class NewFileAction < FileAction
-      # Updates the files content and creates a new commit for it
-      #
-      # Returns false if the ref has been updated while editing the file
-      # Returns false if committing the change fails
-      # Returns false if pushing from the satellite to bare repo failed or was rejected
-      # Returns true otherwise
-      def commit!(content, commit_message, encoding, new_branch = nil)
-        in_locked_and_timed_satellite do |repo|
-          prepare_satellite!(repo)
-
-          # create target branch in satellite at the corresponding commit from bare repo
-          current_ref =
-            if @project.empty_repo?
-              # skip this step if we want to add first file to empty repo
-              Satellite::PARKING_BRANCH
-            else
-              repo.git.checkout({ raise: true, timeout: true, b: true }, ref, "origin/#{ref}")
-              ref
-            end
-
-          file_path_in_satellite = File.join(repo.working_dir, file_path)
-          dir_name_in_satellite = File.dirname(file_path_in_satellite)
-
-          # Prevent relative links
-          unless safe_path?(file_path_in_satellite)
-            Gitlab::GitLogger.error("FileAction: Relative path not allowed")
-            return false
-          end
-
-          # Create dir if not exists
-          FileUtils.mkdir_p(dir_name_in_satellite)
-
-          # Write file
-          write_file(file_path_in_satellite, content, encoding)
-
-          # add new file
-          repo.add(file_path_in_satellite)
-
-          # commit the changes
-          # will raise CommandFailed when commit fails
-          repo.git.commit(raise: true, timeout: true, a: true, m: commit_message)
-
-          target_branch = if new_branch.present? && !@project.empty_repo?
-                            "#{ref}:#{new_branch}"
-                          else
-                            "#{current_ref}:#{ref}"
-                          end
-
-          # push commit back to bare repo
-          # will raise CommandFailed when push fails
-          repo.git.push({ raise: true, timeout: true }, :origin, target_branch)
-
-          # everything worked
-          true
-        end
-      rescue Grit::Git::CommandFailed => ex
-        Gitlab::GitLogger.error(ex.message)
-        false
-      end
-    end
-  end
-end
diff --git a/lib/gitlab/satellite/logger.rb b/lib/gitlab/satellite/logger.rb
deleted file mode 100644
index 6f3f8255aca11e5b9c77bf98bd968a299e3c9756..0000000000000000000000000000000000000000
--- a/lib/gitlab/satellite/logger.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module Gitlab
-  module Satellite
-    class Logger < Gitlab::Logger
-      def self.file_name
-        'satellites.log'
-      end
-
-      def format_message(severity, timestamp, progname, msg)
-        "#{timestamp.to_s(:long)}: #{msg}\n"
-      end
-    end
-  end
-end
diff --git a/lib/gitlab/satellite/merge_action.rb b/lib/gitlab/satellite/merge_action.rb
deleted file mode 100644
index 52e8130956c2e1d5af1735fcc8b2396cefe85d5e..0000000000000000000000000000000000000000
--- a/lib/gitlab/satellite/merge_action.rb
+++ /dev/null
@@ -1,147 +0,0 @@
-module Gitlab
-  module Satellite
-    # GitLab server-side merge
-    class MergeAction < Action
-      attr_accessor :merge_request
-
-      def initialize(user, merge_request)
-        super user, merge_request.target_project
-        @merge_request = merge_request
-      end
-
-      # Checks if a merge request can be executed without user interaction
-      def can_be_merged?
-        in_locked_and_timed_satellite do |merge_repo|
-          prepare_satellite!(merge_repo)
-          merge_in_satellite!(merge_repo)
-        end
-      end
-
-      # Merges the source branch into the target branch in the satellite and
-      # pushes it back to the repository.
-      # It also removes the source branch if requested in the merge request (and this is permitted by the merge request).
-      #
-      # Returns false if the merge produced conflicts
-      # Returns false if pushing from the satellite to the repository failed or was rejected
-      # Returns true otherwise
-      def merge!(merge_commit_message = nil)
-        in_locked_and_timed_satellite do |merge_repo|
-          prepare_satellite!(merge_repo)
-          if merge_in_satellite!(merge_repo, merge_commit_message)
-            # push merge back to bare repo
-            # will raise CommandFailed when push fails
-            merge_repo.git.push(default_options, :origin, merge_request.target_branch)
-
-            # remove source branch
-            if merge_request.remove_source_branch?
-              # will raise CommandFailed when push fails
-              merge_repo.git.push(default_options, :origin, ":#{merge_request.source_branch}")
-              merge_request.source_project.repository.expire_branch_names
-            end
-            # merge, push and branch removal successful
-            true
-          end
-        end
-      rescue Grit::Git::CommandFailed => ex
-        handle_exception(ex)
-      end
-
-      def diff_in_satellite
-        in_locked_and_timed_satellite do |merge_repo|
-          prepare_satellite!(merge_repo)
-          update_satellite_source_and_target!(merge_repo)
-
-          # Only show what is new in the source branch compared to the target branch, not the other way around.
-          # The line below with merge_base is equivalent to diff with three dots (git diff branch1...branch2)
-          # From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B"
-          common_commit = merge_repo.git.native(:merge_base, default_options, ["origin/#{merge_request.target_branch}", "source/#{merge_request.source_branch}"]).strip
-          merge_repo.git.native(:diff, default_options, common_commit, "source/#{merge_request.source_branch}")
-        end
-      rescue Grit::Git::CommandFailed => ex
-        handle_exception(ex)
-      end
-
-      def diffs_between_satellite
-        in_locked_and_timed_satellite do |merge_repo|
-          prepare_satellite!(merge_repo)
-          update_satellite_source_and_target!(merge_repo)
-          if merge_request.for_fork?
-            repository = Gitlab::Git::Repository.new(merge_repo.path)
-            diffs = Gitlab::Git::Diff.between(
-              repository,
-              "source/#{merge_request.source_branch}",
-              "origin/#{merge_request.target_branch}"
-            )
-          else
-            raise "Attempt to determine diffs between for a non forked merge request in satellite MergeRequest.id:[#{merge_request.id}]"
-          end
-
-          return diffs
-        end
-      rescue Grit::Git::CommandFailed => ex
-        handle_exception(ex)
-      end
-
-      # Get commit as an email patch
-      def format_patch
-        in_locked_and_timed_satellite do |merge_repo|
-          prepare_satellite!(merge_repo)
-          update_satellite_source_and_target!(merge_repo)
-          patch = merge_repo.git.format_patch(default_options({ stdout: true }), "origin/#{merge_request.target_branch}..source/#{merge_request.source_branch}")
-        end
-      rescue Grit::Git::CommandFailed => ex
-        handle_exception(ex)
-      end
-
-      # Retrieve an array of commits between the source and the target
-      def commits_between
-        in_locked_and_timed_satellite do |merge_repo|
-          prepare_satellite!(merge_repo)
-          update_satellite_source_and_target!(merge_repo)
-          if merge_request.for_fork?
-            repository = Gitlab::Git::Repository.new(merge_repo.path)
-            commits = Gitlab::Git::Commit.between(
-              repository,
-              "origin/#{merge_request.target_branch}",
-              "source/#{merge_request.source_branch}"
-            )
-          else
-            raise "Attempt to determine commits between for a non forked merge request in satellite MergeRequest.id:[#{merge_request.id}]"
-          end
-
-          return commits
-        end
-      rescue Grit::Git::CommandFailed => ex
-        handle_exception(ex)
-      end
-
-      private
-      # Merges the source_branch into the target_branch in the satellite.
-      #
-      # Note: it will clear out the satellite before doing anything
-      #
-      # Returns false if the merge produced conflicts
-      # Returns true otherwise
-      def merge_in_satellite!(repo, message = nil)
-        update_satellite_source_and_target!(repo)
-
-        message ||= "Merge branch '#{merge_request.source_branch}' into '#{merge_request.target_branch}'"
-
-        # merge the source branch into the satellite
-        # will raise CommandFailed when merge fails
-        repo.git.merge(default_options({ no_ff: true }), "-m#{message}", "source/#{merge_request.source_branch}")
-      rescue Grit::Git::CommandFailed => ex
-        handle_exception(ex)
-      end
-
-      # Assumes a satellite exists that is a fresh clone of the projects repo, prepares satellite for merges, diffs etc
-      def update_satellite_source_and_target!(repo)
-        repo.remote_add('source', merge_request.source_project.repository.path_to_repo)
-        repo.remote_fetch('source')
-        repo.git.checkout(default_options({ b: true }), merge_request.target_branch, "origin/#{merge_request.target_branch}")
-      rescue Grit::Git::CommandFailed => ex
-        handle_exception(ex)
-      end
-    end
-  end
-end
diff --git a/lib/gitlab/satellite/satellite.rb b/lib/gitlab/satellite/satellite.rb
deleted file mode 100644
index 398643d68de2c07a56ba30181786f693dae6219a..0000000000000000000000000000000000000000
--- a/lib/gitlab/satellite/satellite.rb
+++ /dev/null
@@ -1,148 +0,0 @@
-module Gitlab
-  module Satellite
-    autoload :DeleteFileAction, 'gitlab/satellite/files/delete_file_action'
-    autoload :EditFileAction,   'gitlab/satellite/files/edit_file_action'
-    autoload :FileAction,       'gitlab/satellite/files/file_action'
-    autoload :NewFileAction,    'gitlab/satellite/files/new_file_action'
-
-    class CheckoutFailed < StandardError; end
-    class CommitFailed < StandardError; end
-    class PushFailed < StandardError; end
-
-    class Satellite
-      include Gitlab::Popen
-
-      PARKING_BRANCH = "__parking_branch"
-
-      attr_accessor :project
-
-      def initialize(project)
-        @project = project
-      end
-
-      def log(message)
-        Gitlab::Satellite::Logger.error(message)
-      end
-
-      def clear_and_update!
-        project.ensure_satellite_exists
-
-        @repo = nil
-        clear_working_dir!
-        delete_heads!
-        remove_remotes!
-        update_from_source!
-      end
-
-      def create
-        output, status = popen(%W(git clone -- #{project.repository.path_to_repo} #{path}),
-                               Gitlab.config.satellites.path)
-
-        log("PID: #{project.id}: git clone #{project.repository.path_to_repo} #{path}")
-        log("PID: #{project.id}: -> #{output}")
-
-        if status.zero?
-          true
-        else
-          log("Failed to create satellite for #{project.name_with_namespace}")
-          false
-        end
-      end
-
-      def exists?
-        File.exists? path
-      end
-
-      # * Locks the satellite
-      # * Changes the current directory to the satellite's working dir
-      # * Yields
-      def lock
-        project.ensure_satellite_exists
-
-        File.open(lock_file, "w+") do |f|
-          begin
-            f.flock File::LOCK_EX
-            yield
-          ensure
-            f.flock File::LOCK_UN
-          end
-        end
-      end
-
-      def lock_file
-        create_locks_dir unless File.exists?(lock_files_dir)
-        File.join(lock_files_dir, "satellite_#{project.id}.lock")
-      end
-
-      def path
-        File.join(Gitlab.config.satellites.path, project.path_with_namespace)
-      end
-
-      def repo
-        project.ensure_satellite_exists
-
-        @repo ||= Grit::Repo.new(path)
-      end
-
-      def destroy
-        FileUtils.rm_rf(path)
-      end
-
-      private
-
-      # Clear the working directory
-      def clear_working_dir!
-        repo.git.reset(hard: true)
-        repo.git.clean(f: true, d: true, x: true)
-      end
-
-      # Deletes all branches except the parking branch
-      #
-      # This ensures we have no name clashes or issues updating branches when
-      # working with the satellite.
-      def delete_heads!
-        heads = repo.heads.map(&:name)
-
-        # update or create the parking branch
-        repo.git.checkout(default_options({ B: true }), PARKING_BRANCH)
-
-        # remove the parking branch from the list of heads ...
-        heads.delete(PARKING_BRANCH)
-        # ... and delete all others
-        heads.each { |head| repo.git.branch(default_options({ D: true }), head) }
-      end
-
-      # Deletes all remotes except origin
-      #
-      # This ensures we have no remote name clashes or issues updating branches when
-      # working with the satellite.
-      def remove_remotes!
-        remotes = repo.git.remote.split(' ')
-        remotes.delete('origin')
-        remotes.each { |name| repo.git.remote(default_options,'rm', name)}
-      end
-
-      # Updates the satellite from bare repo
-      #
-      # Note: this will only update remote branches (i.e. origin/*)
-      def update_from_source!
-        repo.git.remote(default_options, 'set-url', :origin, project.repository.path_to_repo)
-        repo.git.fetch(default_options, :origin)
-      end
-
-      def default_options(options = {})
-        { raise: true, timeout: true }.merge(options)
-      end
-
-      # Create directory for storing
-      # satellites lock files
-      def create_locks_dir
-        FileUtils.mkdir_p(lock_files_dir)
-      end
-
-      def lock_files_dir
-        @lock_files_dir ||= File.join(Gitlab.config.satellites.path, "tmp")
-      end
-    end
-  end
-end
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index d19695f92fb741c866a23df64f8a277385242de3..80ee572938d7282f210f93d62ed24fac6fff2d25 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -25,7 +25,6 @@ namespace :gitlab do
       check_init_script_exists
       check_init_script_up_to_date
       check_projects_have_namespace
-      check_satellites_exist
       check_redis_version
       check_ruby_version
       check_git_version
@@ -238,37 +237,6 @@ namespace :gitlab do
       end
     end
 
-    def check_satellites_exist
-      print "Projects have satellites? ... "
-
-      unless Project.count > 0
-        puts "can't check, you have no projects".magenta
-        return
-      end
-      puts ""
-
-      Project.find_each(batch_size: 100) do |project|
-        print sanitized_message(project)
-
-        if project.satellite.exists?
-          puts "yes".green
-        elsif project.empty_repo?
-          puts "can't create, repository is empty".magenta
-        else
-          puts "no".red
-          try_fixing_it(
-            sudo_gitlab("bundle exec rake gitlab:satellites:create RAILS_ENV=production"),
-            "If necessary, remove the tmp/repo_satellites directory ...",
-            "... and rerun the above command"
-          )
-          for_more_information(
-            "doc/raketasks/maintenance.md "
-          )
-          fix_and_rerun
-        end
-      end
-    end
-
     def check_log_writable
       print "Log directory writable? ... "
 
@@ -339,7 +307,6 @@ namespace :gitlab do
       check_repo_base_is_not_symlink
       check_repo_base_user_and_group
       check_repo_base_permissions
-      check_satellites_permissions
       check_repos_hooks_directory_is_link
       check_gitlab_shell_self_test
 
@@ -417,29 +384,6 @@ namespace :gitlab do
       end
     end
 
-    def check_satellites_permissions
-      print "Satellites access is drwxr-x---? ... "
-
-      satellites_path = Gitlab.config.satellites.path
-      unless File.exists?(satellites_path)
-        puts "can't check because of previous errors".magenta
-        return
-      end
-
-      if File.stat(satellites_path).mode.to_s(8).ends_with?("0750")
-        puts "yes".green
-      else
-        puts "no".red
-        try_fixing_it(
-          "sudo chmod u+rwx,g=rx,o-rwx #{satellites_path}",
-        )
-        for_more_information(
-          see_installation_guide_section "GitLab"
-        )
-        fix_and_rerun
-      end
-    end
-
     def check_repo_base_user_and_group
       gitlab_shell_ssh_user = Gitlab.config.gitlab_shell.ssh_user
       gitlab_shell_owner_group = Gitlab.config.gitlab_shell.owner_group
diff --git a/lib/tasks/gitlab/enable_automerge.rake b/lib/tasks/gitlab/enable_automerge.rake
deleted file mode 100644
index 3dade9d75b8b9b0905aef24a94eb87c03fe1a58d..0000000000000000000000000000000000000000
--- a/lib/tasks/gitlab/enable_automerge.rake
+++ /dev/null
@@ -1,39 +0,0 @@
-namespace :gitlab do
-  namespace :satellites do
-    desc "GitLab | Create satellite repos"
-    task create: :environment do
-      create_satellites
-    end
-  end
-
-  def create_satellites
-    warn_user_is_not_gitlab
-
-    print "Creating satellites for ..."
-    unless Project.count > 0
-      puts "skipping, because you have no projects".magenta
-      return
-    end
-    puts ""
-
-    Project.find_each(batch_size: 100) do |project|
-      print "#{project.name_with_namespace.yellow} ... "
-
-      unless project.repo_exists?
-        puts "skipping, because the repo is empty".magenta
-        next
-      end
-
-      if project.satellite.exists?
-        puts "exists already".green
-      else
-        print "\n... "
-        if project.satellite.create
-          puts "created".green
-        else
-          puts "error".red
-        end
-      end
-    end
-  end
-end
diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb
index f921dd9cc099f0cfc884a0cd195bb3303db9d3ab..088e34f050c317ab91272c69f0a6d63e5c3d4467 100644
--- a/spec/lib/gitlab/reference_extractor_spec.rb
+++ b/spec/lib/gitlab/reference_extractor_spec.rb
@@ -25,7 +25,7 @@ describe Gitlab::ReferenceExtractor do
     project.team << [@u_bar, :guest]
 
     subject.analyze(%Q{
-      Inline code: `@foo` 
+      Inline code: `@foo`
 
       Code block:
 
@@ -33,7 +33,7 @@ describe Gitlab::ReferenceExtractor do
       @bar
       ```
 
-      Quote: 
+      Quote:
 
       > @offteam
     })
@@ -49,8 +49,8 @@ describe Gitlab::ReferenceExtractor do
   end
 
   it 'accesses valid merge requests' do
-    @m0 = create(:merge_request, source_project: project, target_project: project, source_branch: 'aaa')
-    @m1 = create(:merge_request, source_project: project, target_project: project, source_branch: 'bbb')
+    @m0 = create(:merge_request, source_project: project, target_project: project, source_branch: 'markdown')
+    @m1 = create(:merge_request, source_project: project, target_project: project, source_branch: 'feature_conflict')
 
     subject.analyze("!999, !#{@m1.iid}, and !#{@m0.iid}.")
     expect(subject.merge_requests).to eq([@m1, @m0])
diff --git a/spec/lib/gitlab/satellite/action_spec.rb b/spec/lib/gitlab/satellite/action_spec.rb
deleted file mode 100644
index 0a93676edc3c69cc4a7c6d4553fce696b2f5650f..0000000000000000000000000000000000000000
--- a/spec/lib/gitlab/satellite/action_spec.rb
+++ /dev/null
@@ -1,116 +0,0 @@
-require 'spec_helper'
-
-describe 'Gitlab::Satellite::Action' do
-  let(:project) { create(:project) }
-  let(:user) { create(:user) }
-
-  describe '#prepare_satellite!' do
-    it 'should be able to fetch timeout from conf' do
-      expect(Gitlab::Satellite::Action::DEFAULT_OPTIONS[:git_timeout]).to eq(30.seconds)
-    end
-
-    it 'create a repository with a parking branch and one remote: origin' do
-      repo = project.satellite.repo
-
-      #now lets dirty it up
-
-      starting_remote_count = repo.git.list_remotes.size
-      expect(starting_remote_count).to be >= 1
-      #kind of hookey way to add a second remote
-      origin_uri = repo.git.remote({ v: true }).split(" ")[1]
-
-      repo.git.remote({ raise: true }, 'add', 'another-remote', origin_uri)
-      repo.git.branch({ raise: true }, 'a-new-branch')
-
-      expect(repo.heads.size).to be > (starting_remote_count)
-      expect(repo.git.remote().split(" ").size).to be > (starting_remote_count)
-
-      repo.git.config({}, "user.name", "#{user.name} -- foo")
-      repo.git.config({}, "user.email", "#{user.email} -- foo")
-      expect(repo.config['user.name']).to eq("#{user.name} -- foo")
-      expect(repo.config['user.email']).to eq("#{user.email} -- foo")
-
-
-      #These must happen in the context of the satellite directory...
-      satellite_action = Gitlab::Satellite::Action.new(user, project)
-      project.satellite.lock do
-        #Now clean it up, use send to get around prepare_satellite! being protected
-        satellite_action.send(:prepare_satellite!, repo)
-      end
-
-      #verify it's clean
-      heads = repo.heads.map(&:name)
-      expect(heads.size).to eq(1)
-      expect(heads.include?(Gitlab::Satellite::Satellite::PARKING_BRANCH)).to eq(true)
-      remotes = repo.git.remote().split(' ')
-      expect(remotes.size).to eq(1)
-      expect(remotes.include?('origin')).to eq(true)
-      expect(repo.config['user.name']).to eq(user.name)
-      expect(repo.config['user.email']).to eq(user.email)
-    end
-  end
-
-  describe '#in_locked_and_timed_satellite' do
-
-    it 'should make use of a lockfile' do
-      repo = project.satellite.repo
-      called = false
-
-      #set assumptions
-      FileUtils.rm_f(project.satellite.lock_file)
-
-      expect(File.exists?(project.satellite.lock_file)).to be_falsey
-
-      satellite_action = Gitlab::Satellite::Action.new(user, project)
-      satellite_action.send(:in_locked_and_timed_satellite) do |sat_repo|
-        expect(repo).to eq(sat_repo)
-        expect(File.exists? project.satellite.lock_file).to be_truthy
-        called = true
-      end
-
-      expect(called).to be_truthy
-
-    end
-
-    it 'should be able to use the satellite after locking' do
-      repo = project.satellite.repo
-      called = false
-
-      # Set base assumptions
-      if File.exists? project.satellite.lock_file
-        expect(FileLockStatusChecker.new(project.satellite.lock_file).flocked?).to be_falsey
-      end
-
-      satellite_action = Gitlab::Satellite::Action.new(user, project)
-      satellite_action.send(:in_locked_and_timed_satellite) do |sat_repo|
-        called = true
-        expect(repo).to eq(sat_repo)
-        expect(File.exists? project.satellite.lock_file).to be_truthy
-        expect(FileLockStatusChecker.new(project.satellite.lock_file).flocked?).to be_truthy
-      end
-
-      expect(called).to be_truthy
-      expect(FileLockStatusChecker.new(project.satellite.lock_file).flocked?).to be_falsey
-
-    end
-
-    class FileLockStatusChecker < File
-      def flocked?(&block)
-        status = flock LOCK_EX|LOCK_NB
-        case status
-        when false
-          return true
-        when 0
-          begin
-            block ? block.call : false
-          ensure
-            flock LOCK_UN
-          end
-        else
-          raise SystemCallError, status
-        end
-      end
-    end
-
-  end
-end
diff --git a/spec/lib/gitlab/satellite/merge_action_spec.rb b/spec/lib/gitlab/satellite/merge_action_spec.rb
deleted file mode 100644
index e977261c726a0b7ee294b18482ae36319127a9d3..0000000000000000000000000000000000000000
--- a/spec/lib/gitlab/satellite/merge_action_spec.rb
+++ /dev/null
@@ -1,118 +0,0 @@
-require 'spec_helper'
-
-describe 'Gitlab::Satellite::MergeAction' do
-  include RepoHelpers
-
-  let(:project) { create(:project, namespace: create(:group)) }
-  let(:fork_project) { create(:project, namespace: create(:group), forked_from_project: project) }
-  let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
-  let(:merge_request_fork) { create(:merge_request, source_project: fork_project, target_project: project) }
-
-  let(:merge_request_with_conflict) { create(:merge_request, :conflict, source_project: project, target_project: project) }
-  let(:merge_request_fork_with_conflict) { create(:merge_request, :conflict, source_project: project, target_project: project) }
-
-  describe '#commits_between' do
-    def verify_commits(commits, first_commit_sha, last_commit_sha)
-      commits.each { |commit| expect(commit.class).to eq(Gitlab::Git::Commit) }
-      expect(commits.first.id).to eq(first_commit_sha)
-      expect(commits.last.id).to eq(last_commit_sha)
-    end
-
-    context 'on fork' do
-      it 'should get proper commits between' do
-        commits = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).commits_between
-        verify_commits(commits, sample_compare.commits.first, sample_compare.commits.last)
-      end
-    end
-
-    context 'between branches' do
-      it 'should raise exception -- not expected to be used by non forks' do
-        expect { Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between }.to raise_error(RuntimeError)
-      end
-    end
-  end
-
-  describe '#format_patch' do
-    def verify_content(patch)
-      sample_compare.commits.each do |commit|
-        expect(patch.include?(commit)).to be_truthy
-      end
-    end
-
-    context 'on fork' do
-      it 'should build a format patch' do
-        patch = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).format_patch
-        verify_content(patch)
-      end
-    end
-
-    context 'between branches' do
-      it 'should build a format patch' do
-        patch = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request).format_patch
-        verify_content(patch)
-      end
-    end
-  end
-
-  describe '#diffs_between_satellite tested against diff_in_satellite' do
-    def is_a_matching_diff(diff, diffs)
-      diff_count = diff.scan('diff --git').size
-      expect(diff_count).to be >= 1
-      expect(diffs.size).to eq(diff_count)
-      diffs.each do |a_diff|
-        expect(a_diff.class).to eq(Gitlab::Git::Diff)
-        expect(diff.include? a_diff.diff).to be_truthy
-      end
-    end
-
-    context 'on fork' do
-      it 'should get proper diffs' do
-        diffs = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).diffs_between_satellite
-        diff = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request_fork).diff_in_satellite
-        is_a_matching_diff(diff, diffs)
-      end
-    end
-
-    context 'between branches' do
-      it 'should get proper diffs' do
-        expect{ Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).diffs_between_satellite }.to raise_error(RuntimeError)
-      end
-    end
-  end
-
-  describe '#can_be_merged?' do
-    context 'on fork' do
-      it do
-        expect(Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).can_be_merged?).to be_truthy
-      end
-
-      it do
-        expect(Gitlab::Satellite::MergeAction.new(merge_request_fork_with_conflict.author, merge_request_fork_with_conflict).can_be_merged?).to be_falsey
-      end
-    end
-
-    context 'between branches' do
-      it do
-        expect(Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).can_be_merged?).to be_truthy
-      end
-
-      it do
-        expect(Gitlab::Satellite::MergeAction.new(merge_request_with_conflict.author, merge_request_with_conflict).can_be_merged?).to be_falsey
-      end
-    end
-  end
-
-  describe '#merge!' do
-    let(:merge_request) { create(:merge_request, source_project: project, target_project: project, source_branch: "markdown", should_remove_source_branch: true) }
-    let(:merge_action) { Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request) }
-
-    it 'clears cache of source repo after removing source branch' do
-      project.repository.expire_branch_names
-      expect(project.repository.branch_names).to include('markdown')
-
-      merge_action.merge!
-
-      expect(project.repository.branch_names).not_to include('markdown')
-    end
-  end
-end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 76f6d8c54c4ba2048ab6ed69d7f5234544a1032b..b91687bc09fc9a18f3e565b181beb30420d9ba54 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -165,7 +165,7 @@ describe MergeRequest do
   end
 
   it_behaves_like 'an editable mentionable' do
-    subject { create(:merge_request, source_project: project) }
+    subject { create(:merge_request) }
 
     let(:backref_text) { "merge request #{subject.to_reference}" }
     let(:set_mentionable_text) { ->(txt){ subject.description = txt } }
diff --git a/spec/models/project_services/slack_service_spec.rb b/spec/models/project_services/slack_service_spec.rb
index 69466b11f096dbd8cb53183c0e2e14db8fd253eb..97b60e19e407971a02a182166d24588781254964 100644
--- a/spec/models/project_services/slack_service_spec.rb
+++ b/spec/models/project_services/slack_service_spec.rb
@@ -67,7 +67,7 @@ describe SlackService do
       opts = {
         title: 'Awesome merge_request',
         description: 'please fix',
-        source_branch: 'stable',
+        source_branch: 'feature',
         target_branch: 'master'
       }
       merge_service = MergeRequests::CreateService.new(project,
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 5d40754d59dda7c36b76aa0796fc04fd29aa802b..2fcbd5ae108ae3911b27c314f198d93431953c68 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -91,7 +91,6 @@ describe Project do
   describe 'Respond to' do
     it { is_expected.to respond_to(:url_to_repo) }
     it { is_expected.to respond_to(:repo_exists?) }
-    it { is_expected.to respond_to(:satellite) }
     it { is_expected.to respond_to(:update_merge_requests) }
     it { is_expected.to respond_to(:execute_hooks) }
     it { is_expected.to respond_to(:name_with_namespace) }
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 8e2849691ff0573eacea42e73f1acb4c8bfb6608..05e51532eb878564afd1ad0db0f73cd2e634dcb3 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -40,6 +40,20 @@ describe Repository do
 
       it { is_expected.to be_truthy }
     end
+  end
+
+  describe :can_be_merged? do
+    context 'mergeable branches' do
+      subject { repository.can_be_merged?('0b4bc9a49b562e85de7cc9e834518ea6828729b9', 'master') }
+
+      it { is_expected.to be_truthy }
+    end
+
+    context 'non-mergeable branches' do
+      subject { repository.can_be_merged?('bb5206fee213d983da88c47f9cf4cc6caf9c66dc', 'feature') }
+
+      it { is_expected.to be_falsey }
+    end
 
     context 'non merged branch' do
       subject { repository.merged_to_root_ref?('fix') }
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index 78f2cb56b025667dccff6b2d499d156a0064f03c..042e6352567101f76dca133a1da1c4b5fcda0b97 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -49,8 +49,6 @@ describe API::API, api: true  do
     end
 
     it "should create a new file in project repo" do
-      expect_any_instance_of(Gitlab::Satellite::NewFileAction).to receive(:commit!).and_return(true)
-
       post api("/projects/#{project.id}/repository/files", user), valid_params
       expect(response.status).to eq(201)
       expect(json_response['file_path']).to eq('newfile.rb')
@@ -61,8 +59,9 @@ describe API::API, api: true  do
       expect(response.status).to eq(400)
     end
 
-    it "should return a 400 if satellite fails to create file" do
-      expect_any_instance_of(Gitlab::Satellite::NewFileAction).to receive(:commit!).and_return(false)
+    it "should return a 400 if editor fails to create file" do
+      allow_any_instance_of(Repository).to receive(:commit_file).
+        and_return(false)
 
       post api("/projects/#{project.id}/repository/files", user), valid_params
       expect(response.status).to eq(400)
@@ -80,8 +79,6 @@ describe API::API, api: true  do
     end
 
     it "should update existing file in project repo" do
-      expect_any_instance_of(Gitlab::Satellite::EditFileAction).to receive(:commit!).and_return(true)
-
       put api("/projects/#{project.id}/repository/files", user), valid_params
       expect(response.status).to eq(200)
       expect(json_response['file_path']).to eq(file_path)
@@ -91,32 +88,6 @@ describe API::API, api: true  do
       put api("/projects/#{project.id}/repository/files", user)
       expect(response.status).to eq(400)
     end
-
-    it 'should return a 400 if the checkout fails' do
-      expect_any_instance_of(Gitlab::Satellite::EditFileAction).to receive(:commit!).and_raise(Gitlab::Satellite::CheckoutFailed)
-
-      put api("/projects/#{project.id}/repository/files", user), valid_params
-      expect(response.status).to eq(400)
-
-      ref = valid_params[:branch_name]
-      expect(response.body).to match("ref '#{ref}' could not be checked out")
-    end
-
-    it 'should return a 409 if the file was not modified' do
-      expect_any_instance_of(Gitlab::Satellite::EditFileAction).to receive(:commit!).and_raise(Gitlab::Satellite::CommitFailed)
-
-      put api("/projects/#{project.id}/repository/files", user), valid_params
-      expect(response.status).to eq(409)
-      expect(response.body).to match("Maybe there was nothing to commit?")
-    end
-
-    it 'should return a 409 if the push fails' do
-      expect_any_instance_of(Gitlab::Satellite::EditFileAction).to receive(:commit!).and_raise(Gitlab::Satellite::PushFailed)
-
-      put api("/projects/#{project.id}/repository/files", user), valid_params
-      expect(response.status).to eq(409)
-      expect(response.body).to match("Maybe the file was changed by another process?")
-    end
   end
 
   describe "DELETE /projects/:id/repository/files" do
@@ -129,7 +100,6 @@ describe API::API, api: true  do
     end
 
     it "should delete existing file in project repo" do
-      expect_any_instance_of(Gitlab::Satellite::DeleteFileAction).to receive(:commit!).and_return(true)
       delete api("/projects/#{project.id}/repository/files", user), valid_params
       expect(response.status).to eq(200)
       expect(json_response['file_path']).to eq(file_path)
@@ -140,8 +110,8 @@ describe API::API, api: true  do
       expect(response.status).to eq(400)
     end
 
-    it "should return a 400 if satellite fails to create file" do
-      expect_any_instance_of(Gitlab::Satellite::DeleteFileAction).to receive(:commit!).and_return(false)
+    it "should return a 400 if fails to create file" do
+      allow_any_instance_of(Repository).to receive(:remove_file).and_return(false)
 
       delete api("/projects/#{project.id}/repository/files", user), valid_params
       expect(response.status).to eq(400)
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 29db035b2de9b8847d53a59b060049e66d23a2ac..942768fa25462387c6a01175710623ac62e7e762 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -148,7 +148,7 @@ describe API::API, api: true  do
       it "should return merge_request" do
         post api("/projects/#{project.id}/merge_requests", user),
              title: 'Test merge_request',
-             source_branch: 'stable',
+             source_branch: 'feature_conflict',
              target_branch: 'master',
              author: user,
              labels: 'label, label2'
@@ -171,20 +171,20 @@ describe API::API, api: true  do
 
       it "should return 400 when target_branch is missing" do
         post api("/projects/#{project.id}/merge_requests", user),
-        title: "Test merge_request", source_branch: "stable", author: user
+        title: "Test merge_request", source_branch: "markdown", author: user
         expect(response.status).to eq(400)
       end
 
       it "should return 400 when title is missing" do
         post api("/projects/#{project.id}/merge_requests", user),
-        target_branch: 'master', source_branch: 'stable'
+        target_branch: 'master', source_branch: 'markdown'
         expect(response.status).to eq(400)
       end
 
       it 'should return 400 on invalid label names' do
         post api("/projects/#{project.id}/merge_requests", user),
              title: 'Test merge_request',
-             source_branch: 'stable',
+             source_branch: 'markdown',
              target_branch: 'master',
              author: user,
              labels: 'label, ?'
@@ -198,7 +198,7 @@ describe API::API, api: true  do
         before do
           post api("/projects/#{project.id}/merge_requests", user),
                title: 'Test merge_request',
-               source_branch: 'stable',
+               source_branch: 'feature_conflict',
                target_branch: 'master',
                author: user
           @mr = MergeRequest.all.last
@@ -208,7 +208,7 @@ describe API::API, api: true  do
           expect do
             post api("/projects/#{project.id}/merge_requests", user),
                  title: 'New test merge_request',
-                 source_branch: 'stable',
+                 source_branch: 'feature_conflict',
                  target_branch: 'master',
                  author: user
           end.to change { MergeRequest.count }.by(0)
@@ -228,7 +228,8 @@ describe API::API, api: true  do
 
       it "should return merge_request" do
         post api("/projects/#{fork_project.id}/merge_requests", user2),
-        title: 'Test merge_request', source_branch: "stable", target_branch: "master", author: user2, target_project_id: project.id, description: 'Test description for Test merge_request'
+          title: 'Test merge_request', source_branch: "feature_conflict", target_branch: "master",
+          author: user2, target_project_id: project.id, description: 'Test description for Test merge_request'
         expect(response.status).to eq(201)
         expect(json_response['title']).to eq('Test merge_request')
         expect(json_response['description']).to eq('Test description for Test merge_request')
@@ -258,7 +259,7 @@ describe API::API, api: true  do
 
       it "should return 400 when title is missing" do
         post api("/projects/#{fork_project.id}/merge_requests", user2),
-        target_branch: 'master', source_branch: 'stable', author: user2, target_project_id: project.id
+        target_branch: 'master', source_branch: 'markdown', author: user2, target_project_id: project.id
         expect(response.status).to eq(400)
       end
 
@@ -267,7 +268,7 @@ describe API::API, api: true  do
           post api("/projects/#{project.id}/merge_requests", user),
                title: 'Test merge_request',
                target_branch: 'master',
-               source_branch: 'stable',
+               source_branch: 'markdown',
                author: user,
                target_project_id: fork_project.id
           expect(response.status).to eq(422)
@@ -277,7 +278,7 @@ describe API::API, api: true  do
           post api("/projects/#{fork_project.id}/merge_requests", user2),
                title: 'Test merge_request',
                target_branch: 'master',
-               source_branch: 'stable',
+               source_branch: 'markdown',
                author: user2,
                target_project_id: unrelated_project.id
           expect(response.status).to eq(422)
@@ -286,7 +287,7 @@ describe API::API, api: true  do
 
       it "should return 201 when target_branch is specified and for the same project" do
         post api("/projects/#{fork_project.id}/merge_requests", user2),
-        title: 'Test merge_request', target_branch: 'master', source_branch: 'stable', author: user2, target_project_id: fork_project.id
+        title: 'Test merge_request', target_branch: 'master', source_branch: 'markdown', author: user2, target_project_id: fork_project.id
         expect(response.status).to eq(201)
       end
     end
@@ -302,9 +303,6 @@ describe API::API, api: true  do
 
   describe "PUT /projects/:id/merge_request/:merge_request_id/merge" do
     it "should return merge_request in case of success" do
-      allow_any_instance_of(MergeRequest).
-        to receive_messages(can_be_merged?: true, automerge!: true)
-
       put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user)
 
       expect(response.status).to eq(200)
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 0040718d9be4d0293e818e14b722d11d214e7710..82f62a8709cad58e7334cd5e79122a927063e1cd 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -210,8 +210,8 @@ end
 
 #               diffs_namespace_project_merge_request GET      /:namespace_id/:project_id/merge_requests/:id/diffs(.:format)               projects/merge_requests#diffs
 #             commits_namespace_project_merge_request GET      /:namespace_id/:project_id/merge_requests/:id/commits(.:format)             projects/merge_requests#commits
-#           automerge_namespace_project_merge_request POST     /:namespace_id/:project_id/merge_requests/:id/automerge(.:format)           projects/merge_requests#automerge
-#     automerge_check_namespace_project_merge_request GET      /:namespace_id/:project_id/merge_requests/:id/automerge_check(.:format)     projects/merge_requests#automerge_check
+#           merge_namespace_project_merge_request POST     /:namespace_id/:project_id/merge_requests/:id/merge(.:format)           projects/merge_requests#merge
+#     merge_check_namespace_project_merge_request GET      /:namespace_id/:project_id/merge_requests/:id/merge_check(.:format)     projects/merge_requests#merge_check
 #           ci_status_namespace_project_merge_request GET      /:namespace_id/:project_id/merge_requests/:id/ci_status(.:format)           projects/merge_requests#ci_status
 # toggle_subscription_namespace_project_merge_request POST     /:namespace_id/:project_id/merge_requests/:id/toggle_subscription(.:format) projects/merge_requests#toggle_subscription
 #        branch_from_namespace_project_merge_requests GET      /:namespace_id/:project_id/merge_requests/branch_from(.:format)             projects/merge_requests#branch_from
@@ -233,15 +233,15 @@ describe Projects::MergeRequestsController, 'routing' do
     expect(get('/gitlab/gitlabhq/merge_requests/1/commits')).to route_to('projects/merge_requests#commits', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
   end
 
-  it 'to #automerge' do
-    expect(post('/gitlab/gitlabhq/merge_requests/1/automerge')).to route_to(
-      'projects/merge_requests#automerge',
+  it 'to #merge' do
+    expect(post('/gitlab/gitlabhq/merge_requests/1/merge')).to route_to(
+      'projects/merge_requests#merge',
       namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1'
     )
   end
 
-  it 'to #automerge_check' do
-    expect(get('/gitlab/gitlabhq/merge_requests/1/automerge_check')).to route_to('projects/merge_requests#automerge_check', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+  it 'to #merge_check' do
+    expect(get('/gitlab/gitlabhq/merge_requests/1/merge_check')).to route_to('projects/merge_requests#merge_check', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
   end
 
   it 'to #branch_from' do
diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb
index d9bfdf643080752f3ede55ae554b7f590ba8d3c3..cc64d69361e8a57731a528e0bee56b6c79d89a1a 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -10,7 +10,7 @@ describe MergeRequests::CreateService do
         {
           title: 'Awesome merge_request',
           description: 'please fix',
-          source_branch: 'stable',
+          source_branch: 'feature',
           target_branch: 'master'
         }
       end
diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb
index 0a25fb12f4eaa34e964f97349fa7cb5d9ff197f3..7b564d34d7b40d2b9c3812d6d200ea44775210e2 100644
--- a/spec/services/merge_requests/merge_service_spec.rb
+++ b/spec/services/merge_requests/merge_service_spec.rb
@@ -24,11 +24,6 @@ describe MergeRequests::MergeService do
       it { expect(merge_request).to be_valid }
       it { expect(merge_request).to be_merged }
 
-      it 'should execute hooks with merge action' do
-        expect(service).to have_received(:execute_hooks).
-                               with(merge_request, 'merge')
-      end
-
       it 'should send email to user2 about merge of new merge_request' do
         email = ActionMailer::Base.deliveries.last
         expect(email.to.first).to eq(user2.email)
diff --git a/spec/support/mentionable_shared_examples.rb b/spec/support/mentionable_shared_examples.rb
index f0717e6178198736abbd34558de2ad14c09367a8..e3de0afb44825a6b84a7bb9723e22754dfb7538b 100644
--- a/spec/support/mentionable_shared_examples.rb
+++ b/spec/support/mentionable_shared_examples.rb
@@ -9,7 +9,7 @@ def common_mentionable_setup
   let(:author)  { subject.author }
 
   let(:mentioned_issue)  { create(:issue, project: project) }
-  let(:mentioned_mr)     { create(:merge_request, :simple, source_project: project) }
+  let!(:mentioned_mr)     { create(:merge_request, :simple, source_project: project) }
   let(:mentioned_commit) { project.commit }
 
   let(:ext_proj)   { create(:project, :public) }
diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb
index 8dc687c3580323fec15159974358362c2757dc03..3eab74ba9860be6207a74236e9cf4c91e6afcc74 100644
--- a/spec/support/test_env.rb
+++ b/spec/support/test_env.rb
@@ -57,6 +57,10 @@ module TestEnv
       and_call_original
   end
 
+  def disable_pre_receive
+    allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return(true)
+  end
+
   # Clean /tmp/tests
   #
   # Keeps gitlab-shell and gitlab-test